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

剩下的不会