Codeforces Round #454 D. Seating of Students
来源:互联网 发布:淘宝美工将来有前途么 编辑:程序博客网 时间:2024/06/16 18:16
题意
就是给你
一开始矩阵每个点的坐标就是
然后你需要构造一个新的矩阵
使得新的矩阵没有任何两个坐标在原矩阵中相邻
前言
昨晚看完A就去做D了。。
感觉很浓的构造气息。。
如果n和m大的话,还是很好做的。。
但是小的就不是很好做了。。
在加上很困,于是就没做出来
题解
感觉大体上有两个做法
1.n和m
构造方法还是比较简单的就是奇数大概就是1,3,5,7,9…..2,4,6,8,10…
偶数就反过来
2.随机化
考虑到大的话成功的可能性很大
但是小的话情况不多
于是我们可以考虑随机化。。
大概就是随机填数,然后多次尝试,就可以过了
CODE:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>using namespace std;const int N=100005;int n,m;vector<int> lalal[N];vector<int> a[N],b[N];int fx[4]={-1,0,0,1};int fy[4]={0,-1,1,0};bool ok[N];bool check (int o,int x,int y){ if (x<=0||y<=0) return false; int size=lalal[o].size(); for (int u=0;u<size;u++) if (lalal[o][u]==b[x][y]) return true; return false;}int myrand (){ return rand()*rand()%(n*m)+1;}void solve (){ int num; for (int u=1;u<=n;u++) for (int i=1;i<=m;i++) { num=0; int x=myrand(); while ((num<=(n*m)*2)&&(ok[x]==false||check(x,u-1,i)||check(x,u,i-1))) { x=myrand(); num++; } if (num>(n*m)*2) return ; ok[x]=false; b[u][i]=x; } printf("YES\n"); for (int u=1;u<=n;u++) { for (int i=1;i<=m;i++) printf("%d ",b[u][i]); printf("\n"); } exit(0);}int main(){ srand(87); scanf("%d%d",&n,&m); for (int u=1;u<=n;u++) { a[u].resize(m+5); b[u].resize(m+5); for (int i=1;i<=m;i++) a[u][i]=(u-1)*m+i; } for (int u=1;u<=n;u++) for (int i=1;i<=m;i++) for (int j=0;j<4;j++) { int nx=u+fx[j],ny=i+fy[j]; if (nx>=1&&nx<=n&&ny>=1&&ny<=m) lalal[a[u][i]].push_back(a[nx][ny]); } for (int u=1;u<=100;u++) { memset(ok,true,sizeof(ok)); solve(); } printf("NO\n"); return 0;}
阅读全文