| 题目 | 难度 | 知识点 |
|---|---|---|
| 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
构造,对角线对称写的是一坨垃圾。
#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
不仅有位置,还是一个维度的状态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;
}