题目大意:老师要排座位,要求每个人的四周的邻居不是原来的,求方案
SOL :min(n,m)<4 就暴搜,否则就构造。
#include<bits/stdc++.h> using namespace std; #define N 500017 int n,m,p[N],dx[4] = {0,1,0,-1},dy[4]={1,0,-1,0}; bool check(int i, int j){ int x=(i-1)/m+1,y=(i-1)%m+1,x2=(j-1)/m+1,y2=(j-1)%m+1; for (int k=0;k<4;k++) if (x+dx[k]==x2&&y+dy[k]==y2) return 1; return 0; } void write(int x){if (x<10) {putchar(‘0‘+x); return;} write(x/10); putchar(‘0‘+x%10);} inline void writel(int x){ if (x<0) putchar(‘-‘),x*=-1; write(x); putchar(‘ ‘); } bool dfs(int i) { if (i>=n*m+1) return 1; int x=(i-1)/m+1,y=(i-1)%m+1; for (int j=i;j<=n*m;j++) { swap(p[i],p[j]); if (x^1&&check(p[i],p[(x-2)*m+y])) continue; if (y^1&&check(p[i],p[(x-1)*m+y-1])) continue; if (dfs(i+1))return 1; swap(p[i], p[j]); } return 0; } int main(){ freopen("b.in","r",stdin); scanf("%d%d", &n, &m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) p[(i-1)*m+j]=(i-1)*m+j; if (!dfs(1)) return puts("NO"), 0; puts("YES"); for (int i=1;i<=n;i++,putchar(‘\n‘)) for (int j=1;j<=m;j++) writel(p[(i-1)*m+j]); return 0; }