nefu 1849 两数之和
map统计一下个数就行。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,s,a[N];
map<int,int>vis;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
vis[a[i]]++;
}
cin>>s;
int flag=0;
for(int i=1;i<=n;i++)
{
if(vis[s-a[i]])
{
if(s-a[i]==a[i])
{
if(vis[a[i]]==1)continue;
else {flag=1;break;}
}
else {flag=1;break;}
}
}
if(flag==1)printf("Yes\n");
else printf("No\n");
return 0;
}
nefu 1857 六花的素数(1)
这题看起来好像是素数筛打表什么的,那是迷惑你的,其实是贪心,只要求出x最多能拆成多少个最小素数2,拆了之后可能还剩1或者剩0,那都不用管了。
#include <bits/stdc++.h>
using namespace std;
int n,x;
long long ans;
int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
ans=0;
for(int i=1;i<=n;i++)
{
cin>>x;
ans=ans+x/2;
}
printf("%lld\n",ans);
}
return 0;
}
nefu 1860 黑猫大战桐乃
说起来你可能不信,这题签到题难度,比赛的时候我忘记之前学过的巴什博弈了,自己纸上手工打表找规律找了好几十分钟,还WA了一发…看看我比赛写的AC代码:
#include <bits/stdc++.h>
using namespace std;
long long n,k;
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>k)
{
if(k==1)
{
if(n%2==0)printf("MeiMeiSaiGao\n");
else printf("HeiMaoSaiGao\n");
}
else
{
if(k>=n)printf("HeiMaoSaiGao\n");
else
{
if(k==2)
{
if(n%3==0)printf("MeiMeiSaiGao\n");
else printf("HeiMaoSaiGao\n");
}
else
{
if(k==n-1)printf("MeiMeiSaiGao\n");
else printf("HeiMaoSaiGao\n");
}
}
}
}
return 0;
}
嗯,我们再对比一下用巴什博弈模板写的AC代码:(所以还是要时常复习之前学过的东西啊)
#include <bits/stdc++.h>
using namespace std;
long long n,m;
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
if(n%(m+1)==0)printf("MeiMeiSaiGao\n");//后手必胜
else printf("HeiMaoSaiGao\n");
}
return 0;
}
nefu 1858 六花的素数(2)
这题竟然要用哥德巴赫猜想(1e7以内显然是正确的,嗯,因为打表出来验证了一下就是正确的)
哥德巴赫猜想:任何一个大于2的偶数都可以拆成两个素数之和。
其他的看代码注释吧,应该写得很详细了。
#include <bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int n,x,mx,mx1,mx2,cnt,ans,prime[N];
bool flag[N];
void get_prime()
{
memset(flag,1,sizeof(flag));
flag[1]=0;
for(int i=2;i<=N;i++)
{
if(flag[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&i*prime[j]<=N;j++)
{
flag[i*prime[j]]=0;
if(i%prime[j]==0)break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
get_prime();
while(cin>>n)
{
ans=0;
while(n--)
{
cin>>x;
if(x<=3)
{
if(x==1)mx=0;
if(x==2||x==3)mx=1;
}
else//x>=4时
{
if(x&1)//x是奇数,拆成两个数为奇数+偶数,而这两个数又要尽可能的出现素数,所以要让那个偶数为2
{
//x不拆的情况,直接判断x是否为素数
if(flag[x])mx1=1;
else mx1=0;
//x拆成2个数的情况,其中一个数是偶数素数2,判断另一个数x-2是否为素数
if(flag[x-2])mx2=2;
else mx2=1;
mx=max(mx1,mx2);
}
else mx=2;//哥德巴赫猜想,x>=4的偶数必然能拆分成两个素数,贡献素数个数为2
}
ans=ans+mx;
}
printf("%d\n",ans);
}
return 0;
}
nefu 1850 矩阵距离
将原矩阵中1的位置入队,之后依次将其出队开始BFS,记录最短步数。
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N][N];
int n,m,ans[N][N],vis[N][N];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
struct node
{
int x,y,flag,cnt;//flag是为了区分原矩阵中的某个位置的元素是0还是1
};
queue<node>q;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='1')
{
q.push({i,j,1,0});
vis[i][j]=1;
}
}
while(!q.empty())//开始BFS
{
node tmp=q.front();q.pop();
int x=tmp.x;
int y=tmp.y;
ans[x][y]=tmp.cnt;
for(int i=0;i<4;i++)
{
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&vis[nx][ny]==0)
{
q.push({nx,ny,0,tmp.cnt+1});
vis[nx][ny]=1;
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
j==m?printf("%d\n",ans[i][j]):printf("%d ",ans[i][j]);
return 0;
}