牛客小白月赛牛客小白月赛106【题解待补】

80 阅读3分钟
题目难度知识点
A 最后DISCO签到
B 末日DISCO构造
C 明日DISCO暴力模拟
D 太阳系DISCO★★多重状态bfs/分层图

最后DISCO

//只需处理a^b这里就行,a其实要么奇数,要么是偶数只需用1,2就行了,b的话只需特判0就。
#include<bits/stdc++.h>
using namespace std;
int a,b,c,d;
int main(void)
{
    cin>>a>>b>>c>>d;
    if(a&1) a=1;
    else a=2;
    if(b==0) a=1;
    else b=1;
    long long int sum=1ll*pow(a,b)*c+d;
    if(sum&1) puts("YES");
    else puts("NO");
    return 0;
}

末日DISCO

image.png 构造,对角线对称写的是一坨垃圾。

#include<bits/stdc++.h>
using namespace std;
const int N=510;
typedef long long int LL;
int a[N][N],n,cnt=1;
int main(void)
{
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int x=i,y=1;
        vector< pair<int,int> >ve;
        while(1)
        {
            ve.push_back({x,y});
            x--,y++;
            if(x<=0||y>n) break;
        }
        for(int j=0,z=ve.size()-1;j<ve.size()/2;j++,z--)
        {
            a[ve[j].first][ve[j].second]=cnt;
            a[ve[z].first][ve[z].second]=cnt++;
        }
    }
    for(int i=2;i<=n;i++)
    {
        int x=n,y=i;
        vector< pair<int,int> >ve;
        while(1)
        {
            ve.push_back({x,y});
            x--,y++;
            if(x<=0||y>n) break;
        }
        for(int j=0,z=ve.size()-1;j<ve.size()/2;j++,z--)
        {
            a[ve[j].first][ve[j].second]=cnt;
            a[ve[z].first][ve[z].second]=cnt++;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(a[i][j]==0) a[i][j]=cnt++;
            cout<<a[i][j]<<" ";
        }
        puts("");
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int a[N][N],n,cnt=1;
int main(void)
{
    cin>>n;
    for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++) a[i][j]=cnt++;
    for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++) a[i][j]=a[j][i];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cout<<a[i][j]<<" ";
        }
        cout<<'\n';
    }
    return 0;
}

明日DISCO

暴力枚举变就行了,需要注意的是最后是全为0,因为棋盘的周围为0且无法变换。

#include<bits/stdc++.h>
using namespace std;
const int N=510;
typedef long long int LL;
int a[N][N],n;
int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0};
void solve(int x,int y)
{
    vector<int>ve;
    for(int i=0;i<4;i++)
    {
        int tempx=x+dx[i],tempy=y+dy[i];
        ve.push_back(a[tempx][tempy]);
    }
    sort(ve.begin(),ve.end());
    if(a[x][y]<ve[0]) a[x][y]=ve[0];
    else if(a[x][y]>ve[3]) a[x][y]=ve[3];
}
int main(void)
{
    cin>>n;
    for(int i=1;i<=n;i++) 
        for(int j=1;j<=n;j++) cin>>a[i][j];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++) solve(i,j);
    }
    set<int>st;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) st.insert(a[i][j]);
    if(st.size()==1 && *st.begin()==0) puts("YES");
    else puts("NO");
    return 0;
}

太阳系DISCO

image.png 不仅有位置,还是一个维度的状态k,k最多用一次,因为一次n/2,二次n/2一共跑了一圈就是没跑。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
int dist[N][2],st[N][2],n,k,a,b,x,y;
void bfs()
{
    k=min(1,k);
    queue< pair<int,int> >q; q.push({a,k});
    st[a][k]=1,dist[a][k]=0;
    while(q.size())
    {
        auto temp=q.front(); q.pop();
        int u=temp.first,cnt=temp.second;
        if(u==b)
        {
            cout<<dist[u][cnt];
            return;
        }
        int tempx=(u+x-1)%n+1;
        if(st[tempx][cnt]==0)
        {
            st[tempx][cnt]=1,dist[tempx][cnt]=dist[u][cnt]+1;
            q.push({tempx,cnt});
            
        }
        tempx=(u-y-1+n)%n+1;
        if(st[tempx][cnt]==0)
        {
            st[tempx][cnt]=1,dist[tempx][cnt]=dist[u][cnt]+1;
            q.push({tempx,cnt});
        }
        if(cnt)
        {
            tempx=(u+n/2-1)%n+1;
            if(st[tempx][cnt-1]==0)
            {
                st[tempx][cnt-1]=1,dist[tempx][cnt-1]=dist[u][cnt]+1;
                q.push({tempx,cnt-1});
            }
        }
    }
    puts("-1");
}
int main(void)
{
    cin>>n>>k>>a>>b>>x>>y;
    bfs();
    return 0;
}