newbie难度——暴力枚举
740 - 1743A
给出的样例能够理解,如果有n个数字不能选,要排四个数字,这四个数字只有两个不同,并且这两个相同的会各自出现两次,有6种排列方式,那如果给出小于样例n的数字,就还需要计算选出哪两个数字
这个不用预处理出排列组合数,直接根据定义计算就够了,因为只选出两个数进行组合
不要忘记去掉多余的输入
#include<bits/stdc++.h>using namespace std;signed main()
{int t;cin>>t;while(t--){int n;cin>>n;for(int i=1;i<=n;i++){int x;cin>>x;}n=10-n;// cout<<n<<endl;int ans=0;ans=n*(n-1)/2;cout<<ans*6<<endl;}return 0;
}
720 - 1750B
几个零和几个一产生最大的价值
暴力统计就行了吧这题
别想简单了,是看哪一种组合大吗?
如果有连续零串,或者连续1串,大于组合串的时候是什么时候
现在怎么找到连续的零串或者连续的1串呢
直接循环遍历,用两个变量分别记录
两个 2 ∗ 1 0 5 2*10^5 2∗105不会爆时间复杂度吗
那要怎么优化
#include<bits/stdc++.h>using namespace std;signed main()
{int t;cin>>t;while(t--){int n;cin>>n;string s;cin>>s;int ans=0;for(int i=0;i<n;i++)if(s[i]=='1') ans++;if(ans==n) cout<<ans*ans<<endl;else if(ans==0) cout<<n*n<<endl;else cout<<ans*(n-ans)<<endl;}return 0;
}
那要如何找到最长连续子串?
诶呀我去,简直不要太聪明了,这样的做法,如果相同就让lg一直增加,遇到不同就回归1
#include<bits/stdc++.h>
#define int long long
using namespace std;signed main()
{int t;cin>>t;while(t--){int n;cin>>n;string s;cin>>s;int ans=0;for(int i=0;i<n;i++)if(s[i]=='1') ans++;ans=ans*(n-ans);int lg=1;int maxn=0;for(int i=1;i<n;i++){if(s[i]==s[i-1]){lg++;}else{maxn=max(maxn,lg*lg);lg=1;}}maxn=max(maxn,lg*lg);ans=max(ans,maxn);cout<<ans<<endl;}return 0;
}
上面的代码没有过后台样例5
没开longlong,笑飞了
事实证明是爆了,你第一打的时候计算时间复杂度的时候就已经说明了呢
950 - 1676D
题目要求找到使 “主教攻击的所有单元格之和为最大”,由于对角线攻击的性质,需要找到对角线能产生价值最大的位置,n和m最大仅为200,用递归去找所有对角线上的所有数应该不会爆栈
为什么得不到正确的答案,感觉自己想的没有错啊
#include<bits/stdc++.h>using namespace std;
int n,m;
const int N=210;
int g[N][N];
int ul,ur,dl,dr;int findul(int x,int deep)
{if(deep<1||deep>n||x<1||x>m) return 0;if(deep==1||deep==n||x==1||x==m){return g[deep][x];}ul+=findul(x-1,deep-1);
}int findur(int x,int deep)
{if(deep<1||deep>n||x<1||x>m) return 0;if(deep==1||deep==n||x==1||x==m){return g[deep][x];}ur+=findur(x+1,deep-1);
}int finddr(int x,int deep)
{if(deep<1||deep>n||x<1||x>m) return 0;if(deep==1||deep==n||x==1||x==m){return g[deep][x];}dr+=finddr(x+1,deep+1);
}int finddl(int x,int deep)
{if(deep<1||deep>n||x<1||x>m) return 0;if(deep==1||deep==n||x==1||x==m){return g[deep][x];}dl+=finddl(x-1,deep+1);
}signed main()
{int t;cin>>t;while(t--){int ans=0;cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)cin>>g[i][j];}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){ul+=findul(j-1,i-1),dl+=finddl(j-1,i+1),ur+=findur(j+1,i-1),dr+=finddr(j+1,i+1);ans=max(ans,ul+ur+dl+dr-3*g[i][j]);cout<<ul+ur+dl+dr-3*g[i][j]<<' ';}cout<<endl;ul=0,ur=0,dl=0,dr=0;}cout<<ans<<endl;}return 0;
}
感觉是递归没有设计好,用递归还得判断递归起始点的边界情况,有点子麻烦
还是不太清楚什么题目适合递归
#include<bits/stdc++.h>using namespace std;
const int N=210;
int g[N][N];signed main()
{int t;cin>>t;while(t--){int n,m;cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>g[i][j];}}int res=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){int now=0;int u=i,v=j;while(u>=0&&u<n&&v>=0&&v<m){now+=g[u][v];u--;v--;}u=i,v=j;while(u>=0&&u<n&&v>=0&&v<m){now+=g[u][v];u++;v--;}u=i,v=j;while(u>=0&&u<n&&v>=0&&v<m){now+=g[u][v];u++;v++;}u=i,v=j;while(u>=0&&u<n&&v>=0&&v<m){now+=g[u][v];u--;v++;}// cout<<now-3*g[i][j]<<' ';res=max(res,now-3*g[i][j]);}// cout<<endl;}cout<<res<<endl;}return 0;
}
980 - 1562B
感觉就是让我们找质数的意思
找到删除哪个数字后,判断他是不是质数,不是质数直接输出位数和数字即可
枚举删除的位置,删除的位数等等 \\
看了题解觉得十分有道理,并决定着手实现一遍
#include<bits/stdc++.h>using namespace std;
const int N=100;
int prime[N];signed main()
{int t;cin>>t;prime[1]=1;for(int i=2;i<=100;i++){for(int j=2;j*j<=i;j++){if(i%j==0) {prime[i]=1;}}}while(t--){int n;cin>>n;string shu;cin>>shu;int flag=0;for(int i=0;i<n;i++){if(shu[i]=='1'||shu[i]=='4'||shu[i]=='6'||shu[i]=='8'||shu[i]=='9'){puts("1");cout<<shu[i]<<endl;flag=1;break;}}if(flag) continue;for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){if(prime[(shu[i]-'0')*10+shu[j]-'0']){puts("2");cout<<shu[i]<<shu[j]<<endl;flag=1;break;}}if(flag) break;}}return 0;
}
1040 - 1598B
判断收否可以把学生分成两个小组即可
首先肯定得在满足人数大于一半的星期中排除
在这些列中枚举,如果能做到各自代表不同的数
#include<bits/stdc++.h>using namespace std;void solve()
{int n;cin>>n;vector<vector<int> > g(n+1,vector<int>(6,0));vector<int> sum(6,0);for(int i=1;i<=n;i++){for(int j=1;j<=5;j++){cin>>g[i][j];if(g[i][j]==1) sum[j]++;}}//int avg=n/2;vector<int> col;for(int j=1;j<=5;j++){if(sum[j]>=avg) col.push_back(j);// cout<<sum[j]<<endl;}for(int i=0;i<col.size();i++){for(int j=i+1;j<col.size();j++){vector<int> st(n+1,0);int u=col[i],v=col[j];int same=0;for(int k=1;k<=n;k++){if(g[k][u]!=g[k][v]){st[u]+=g[k][u];st[v]+=g[k][v];}else{same++;}}if(st[u]>=avg&&st[v]+same>=avg||st[v]>=avg&&st[u]+same>=avg){puts("YES");return;}// cout<<u<<' '<<v<<' '<<st[u]<<' '<<st[v]<<' '<<same<<endl;}}puts("NO");return ;
}signed main()
{int t;cin>>t;while(t--){solve();}return 0;
}
我的后台测试样例2错
看了官方题解,我觉得我们在处理相同和不同有一样的思路
知道了,因为我的st
#include<bits/stdc++.h>using namespace std;void solve()
{int n;cin>>n;vector<vector<int> > g(n+1,vector<int>(n+1,0));for(int i=1;i<=n;i++){for(int j=1;j<=5;j++){cin>>g[i][j];}}for(int i=1;i<=5;i++){for(int j=i+1;j<=5;j++){vector<int> st(6,0);//一定是6,如果是n<6就死翘翘int same=0;for(int k=1;k<=n;k++){if(g[k][i]==1) st[i]++;if(g[k][j]==1) st[j]++;if(g[k][i]==0&&g[k][j]==0){same++;}}if(st[i]>=n/2&&st[j]>=n/2&&same==0){puts("YES");return ;}}}puts("NO");return ;
}signed main()
{int t;cin>>t;while(t--){solve();}return 0;
}