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;
}