A 最后DISCO
快速幂再模2,看最后结果是1还是0
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,b,c,d;
int quick(int a, int b){
int res=1;
while(b){
if(b&1){
res=res*a%2;
}
b>>=1;
a=a*a%2;
}
return res;
}
signed main(){
cin>>a>>b>>c>>d;
int ans=(quick(a,b)*c%2+d)%2;
if(ans&1)cout<<"YES";
else cout<<"NO";
}
B 末日DISCO
构造题,要构造一个n * n的矩阵,把n-1 * n-1的构造好的矩阵取最后一列放入新的一行(第n行)内,而新的一列再用当前矩阵的最大值加1来填充,起始矩阵为1,具体构造可以看代码
#include<bits/stdc++.h>
using namespace std;
int n,g[505][505];
int main(){
cin>>n;
g[1][1]=1;
int cnt=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=n-1;j++)g[i][j]=g[j][i-1];
for(int j=1;j<=i;j++){
cnt++;
g[j][i]=cnt;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)cout<<g[i][j]<<' ';
cout<<'\n';
}
return 0;
}
C 明日DISCO
如果相邻的格子上的数同号且都不为0则输出NO,因为这样的情况下两者会相互“卡住”
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,g[505][505];
signed main(){
cin>>n;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)cin>>g[i][j];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(g[i][j]*g[i][j-1]>0){
cout<<"NO\n";
return 0;
}
if(g[i][j]*g[i][j+1]>0){
cout<<"NO\n";
return 0;
}
if(g[i][j]*g[i-1][j]>0){
cout<<"NO\n";
return 0;
}
if(g[i][j]*g[i+1][j]>0){
cout<<"NO\n";
return 0;
}
}
}
cout<<"YES\n";
}
D 太阳系DISCO
首先从a到b可以看成从0到(b-a+n)%n,因为用两次技能就走回来了,所以只有用和不用的区别。那么先把不用技能时(到b)的最小步数求出来,再看用了一次之后(到(b+n/2)%n)的最小步数,取最小值就可以了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k,a,b,x,y,g[200007];
signed main(){
cin>>n>>k>>a>>b>>x>>y;
b=(b-a+n)%n;
for(int i=0;i<n;i++)g[i]=1e9;
for(int i=0;i<=n/__gcd(x,n);i++){
g[(i*x)%n]=min(i,g[(i*x)%n]);//顺时针走
}
int ans=1e9;
for(int i=0;i<=n/__gcd(y,n);i++){
ans=min(ans,g[(b+i*y)%n]+i);//逆时针走
}
if(k!=0){
for(int i=0;i<=n/__gcd(y,n);i++){
ans=min(ans,g[(b+i*y+(n/2))%n]+i+1);//用一次技能走
}
}
if(ans!=1e9)
cout<<ans<<'\n';
else cout<<-1<<'\n';
// return 0;
}
剩下的不会