链接:http://qscoj.cn/problem/72/
喵哈哈村的木星传说(一)
发布时间: 2017年4月11日 20:01 最后更新: 2017年4月11日 20:01 时间限制: 1000ms 内存限制: 128M
喵哈哈村有一个挂在空中的木星爷爷,每天晚上都讲一些故事。而星星同学,作为木星爷爷的听众,为了报答,于是每天晚上都会为他解决一个问题。
今天,星星同学要为木星爷爷解决这样一个问题:
给一个n*n的方阵,请将这个方阵顺时针旋转90°。
本题包含若干组测试数据。
第一行一个n,表示这个方阵是n*n的方阵。
接下来n行,每行n个整数,表示方阵内的元素a[i][j]。
满足 1<=n<=50,abs(a[i][j])<=1e9
输出顺时针旋转90°之后的方阵。
7 4 1 8 5 2 9 6 3
题解:找规律
#include<bits/stdc++.h> using namespace std; const int maxn=55; int a[maxn][maxn],b[maxn][maxn]; int main(){ int n; while(cin>>n){ for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { b[j][n-i-1]=a[i][j]; } for(int i=0;i<n;i++){ for(int j=0;j<n;j++) { if(j!=n-1)cout<<b[i][j]<<" "; else cout<<b[i][j]<<endl; } } } }
喵哈哈村的木星传说(二)
发布时间: 2017年4月11日 14:39 时间限制: 1000ms 内存限制: 128M
喵哈哈村有一个挂在空中的木星爷爷,每天晚上都讲一些故事。而星星同学,作为木星爷爷的听众,为了报答,于是每天晚上都会为他解决一个问题。
今天,星星同学要为木星爷爷解决这样一个问题:
单词分类。
两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等。
例如:
“AABAC”,它和“CBAAA”就可以归为一类,而和“AAABB”就不是一类。
现在有N个单词,所有单词均由大写字母组成,每个单词的长度不超过100。
你要告诉我这些单词会被分成几类。
本题包含若干组测试数据。
第一行一个N,表示有N个单词。
接下来N行,每行一个单词s[i]。
满足N<=100,strlen(s[i])<=100
输出这些单词会被分成几类。
2
题解1:比较字母出现次数,分组tot++,标记
#include<bits/stdc++.h> using namespace std; const int maxn=105; int num[maxn][26],vis[maxn]; int main(){ int N;string s; while(cin>>N){ int tot=0; memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); for(int i=0;i<N;i++){ cin>>s; for(int j=0;j<s.size();j++)num[i][s[j]-'A']++; } for(int i=0;i<N;i++){ if(vis[i]==1)continue; for(int k=0;k<N;k++){ if(!vis[k]&&k!=i){ if(memcmp(num[i],num[k],26*sizeof(int))==0){ //比较,memcmp(对象1,对象2,字节长(类型)) 相同为0 vis[k]=1; } } } tot++; } cout<<tot<<endl; } }
题解2:
考虑每一个字符串,我们观察知道字符串的字母顺序实际上是没有关系的。
那么我们首先将字符串内的字符排序,然后再看看一共有多少种字符串就好了。
#include<bits/stdc++.h> using namespace std; set<string> S;//同样字符串只出现一次 int n; int main(){ while(cin>>n){ S.clear(); for(int i=0;i<n;i++){ string s; cin>>s; sort(s.begin(),s.end());//字符串排序方法 S.insert(s);//插入 } cout<<S.size()<<endl; } }
喵哈哈村的木星传说(三)
发布时间: 2017年4月11日 20:01 最后更新: 2017年4月11日 20:02 时间限制: 1000ms 内存限制: 128M
喵哈哈村有一个挂在空中的木星爷爷,每天晚上都讲一些故事。而星星同学,作为木星爷爷的听众,为了报答,于是每天晚上都会为他解决一个问题。
今天,星星同学要为木星爷爷解决这样一个问题:
给出长度为N的数列a[i],每次可以从最左边或者最右边取走一个数,第i次取数得到的价值是i * a[i]。求价值之和最大的取数方案。
本题包含若干组测试数据。
第一行一个n,表示数列的长度。
第二行n个整数,分别表示数列里的元素a[i]。
满足 1<=n<=2000,0<=a[i]<=1000
输出最多和的答案。
5 1 3 1 5 2
43
题解:
考虑dp[i][j]表示左边选了i个,右边选了j个dp的最大值。
转移方程dp[i][j]=max(f[i-1][j]+(i+j)*a[i],f[i][j-1]+(i+j)*a[n-j+1]);
#include <bits/stdc++.h> using namespace std; const int maxn=2005; int a[maxn],dp[maxn][maxn]; int main(){ int n; while(cin>>n){ memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++)cin>>a[i]; for(int i=0;i<=n;i++) for(int j=0;j<=n-i;j++){ dp[i+1][j+1]=max(dp[i][j+1]+(i+j)*a[i],dp[i+1][j]+(i+j)*a[n+1-j]); } int ans=0; for(int i=0;i<=n;i++)ans=max(ans,dp[i+1][n+1-i]); cout<<ans<<endl; } }
或
#include <bits/stdc++.h> using namespace std; const int maxn=2005; int n; int a[maxn],dp[maxn][maxn]; int dfs(int i,int j){ if(i<0||j<0) return 0; if(dp[i][j]) return dp[i][j]; dp[i][j]=max(dfs(i-1,j)+(i+j)*a[i],dfs(i,j-1)+(i+j)*a[n+1-j]); return dp[i][j]; } int main(){ while(cin>>n){ memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++)cin>>a[i]; int ans=0; for(int i=0;i<=n;i++){ ans=max(ans,dfs(i,n-i)); } cout<<ans<<endl; } }