今天下午也是小小的做了一下,OI,也是感觉手感火热啊,之前无意间看到的那个哥德巴赫定理今天就用到了,我以为根本用不到的,当时也只是感兴趣看了一眼,还是比较激动啊
话不多说,直接开始看题
World Fragments I
题意:就是说给你两个二进制的数,然后有一个变化规则,就是从x中选择一位数(其实也就是选择1)然后x可以选择减去或者加上这个数,然后问你最少多少次可以让x变成y,如果不可能变成则输出-1
思路:这题是个签到题,但是我当时以为不能存在-1,导致错了两发
首先什么时候是-1呢?就是x为0,但是y不为0,因此没法从x中选出1,导致没法产生变化,因此输出-1
但是对于别的情况直接输出x和y的差值的绝对值即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
string x;
string y;
signed main()
{
cin >> x >> y;
reverse(x.begin(), x.end());
reverse(y.begin(), y.end());
int sum1 = 0, sum2 = 0;
for (int i = 0; i < x.length(); i++)
{
if (x[i] == '1') {
sum1 += (1LL << i);
}
}
for (int i = 0; i < y.length(); i++)
{
if (y[i] == '1')
{
sum2 += (1LL << i);
}
}
if(sum1==0&&sum2!=0)
cout<<"-1\n";
else
cout << abs(sum1 - sum2)<<"\n";
return 0;
}
Until the Blue Moon Rises
题意:就是说给你n个数,然后每两个数之间都可以自行一个加一,一个减一,然后问你最后能否让这n个数都变成素数,如果可以输出YES,不行就是NO
思路:这题其实才是我第一个做出来的因为是英文提面,所以我这个英语贵物只能先看题目比较短的进行翻译了,思路就是强哥德巴赫定理——任意一个大于2的偶数都可以拆分成两个质数的和
我们因此分三种情况
1.只有一个数,我们只需要判断那一个数是否是质数,如果是则是yes,否则是no
2.有两个数,我们需要所有数的和sum是奇数还是偶数,如果是偶数,那么根据强哥德巴赫定理来说,一定可以拆分成功,为yes,如果是奇数,那么一定是一个偶数一个奇数,偶数只有2是质数,如果sum-2也是质数,那么就说明是yes,否则是no
3.大于等于三个数,如果sum>=2*n那么就是yes,最小的质数就是n个2的情况,根据若哥德巴赫定理就可以推出来 任何一个大于7的奇数都能被表示成三个奇质数的和。(一个质数可以被多次使用)
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int a[200005];
int sum=0;
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
if(n==1)
{
if(a[1]==1)
{
cout<<"NO\n";
return 0;
}
for(int i=2;i<=sqrt(a[1]);i++)
{
if(a[1]%i==0)
{
cout<<"NO\n";
return 0;
}
}
cout<<"YES\n";
}
else if(n==2)
{
if(sum%2==0)
{
if(sum>2)
{
cout<<"YES\n";
return 0 ;
}
else
{
cout<<"NO\n";
return 0 ;
}
}
else
{
int q=sum-2;
if(q==1)
{
cout<<"NO\n";
return 0;
}
for(int i=2;i<=sqrt(q);i++)
{
if(q%i==0)
{
cout<<"NO\n";
return 0;
}
}
cout<<"YES\n";
}
}
else
{
if(sum>=2*n)
cout<<"YES\n";
else
cout<<"NO\n";
}
return 0;
}
Ama no Jaku
题意:是说让所有的第i行的最小值大于 第i列的最大值
思路:仔细分析一下就会发现我只要让整个矩阵都变成一个数就可以完成这项操作了,因此我们再细推会发现,如果第一位相同的话,那么后面每一个数都相同,第一位不同的话,后续每一位都不同,然后去计算最小改变次数即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
char s[2005][2005];
int cnth,cntl;
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>s[i][j];
}
}
for(int i=2;i<=n;i++)
{
if(s[i][1]==s[1][1])
{
for(int j=2;j<=n;j++)
{
if(s[i][j]!=s[1][j])
{
cout<<"-1\n";
return 0;
}
}
}
else
{
cnth++;
for(int j=2;j<=n;j++)
{
if(s[i][j]==s[1][j])
{
cout<<"-1\n";
return 0;
}
}
}
}
for(int i=2;i<=n;i++)
{
if(s[1][i]!=s[1][1])
{
cntl++;
}
}
cout<<min(cnth,n-cnth)+min(cntl,n-cntl)<<"\n";
return 0;
}
Koraidon, Miraidon and DFS Shortest Path
题意:就是说用dfs去实现bfs的思路去找到单源最短路径
思路:深搜跑一遍,看看到了同一个点是否会出现不同的值,如果存在不同那就是no否则就是yes
#include<bits/stdc++.h>
using namespace std;
int t;
int n,m;
int d[500005];
int u,v;
bool flag,vis[500005];
vector<int> e[500005];
void dfs(int v)
{
if(!flag)
return;
vis[v]=true;
for (auto u:e[v])
{
if (vis[u])
continue;
if (!d[u])
d[u]=d[v]+1;
else if(d[u]!=d[v]+1)
flag=false;
dfs(u);
}
vis[v]=false;
}
void solve()
{
flag=true;
for (int i=1;i<=n;i++)
{
e[i].clear();
vis[i]=false;
d[i]=0;
}
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>u>>v;
e[u].push_back(v);
}
dfs(1);
cout<<(flag?"Yes":"No")<<endl;
}
signed main()
{
int t;
cin >> t;
while(t--)
solve();
return 0;
}