题意: 给出 n 、m, 表示原来有 n*m 的矩阵形的人,每个人的标号是从1 到 n*m。 要你重新排列,使得原来相邻的人变得不相邻,输出排列后的标号。
相邻的定义:上下挨着,或者左右挨着。
tags: 蛇皮题。。好费时间,还不如去做E题。。
瞎搞做的,,分三种情况,
1】n<5,m<5时,直接暴搜。直观上看复杂度是16^16,但其实大部分的情况会在中途舍弃掉,并不会慢。
2】m>=5 时,奇数列放前面,偶数列放后面,再把偶数行偏移一下就 OK。
比如 2*5, 就是1 3 5 2 4
7 9 6 8 10
3】m<5,但 n>=5 时, 也是和 2】一样,只不过麻烦点。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 200005; int a[100][100], n, m, ans[100][100]; bool vis[N]; bool XL(int x, int y) { if(x > y) swap(x, y); return (y-x==m) || ((x%m!=0) && (x+1==y)); } bool dfs(int r, int c, int u) { a[r][c] = u; vis[u] = true; if(r==n && c==m) { ans[r][c] = u; return true; } int tr = r, tc = c+1; if(tc > m) tr=r+1, tc=1; rep(i, 1, n*m) if(!vis[i]) { if(tc!=1 && XL(u, i)) continue; if(tr>1 && XL(a[tr-1][tc], i)) continue; if( dfs(tr, tc, i) ) { ans[r][c] = u; return true; } } a[r][c] = 0; vis[u] = false; return false; } int num[N][6], num2[N][6]; int main() { scanf("%d%d", &n, &m); if(n<5 && m<5) { bool flag = false; rep(i,1,n*m) if( dfs(1, 1, i) ) { puts("YES"); rep(ci,1,n) rep(cj,1,m) printf("%d%c", a[ci][cj], " "[cj==m]); flag = true; break; } if(!flag) puts("NO"); } else if(m >= 5) { puts("YES"); int ans1, tmp, tmp2; rep(i,1,n) rep(j,1,m) { tmp = (m+1)/2, tmp2 = (i-1)*m; if(i&1) { if(j==1) ans1 = (m&1) ? (i*m-1) : (i*m); else { if(j <= tmp+1) ans1 = tmp2+2*(j-1)-1; else ans1 = tmp2+(j-tmp-1)*2; } } else { if(j <= tmp) ans1 = tmp2+2*j-1; else ans1 = tmp2+(j-tmp)*2; } printf("%d%c", ans1, " "[j==m]); } } else { puts("YES"); int ans1, tmp, tmp2; rep(i,1,n) rep(j,1,m) num[i][j] = m*(i-1)+j; rep(j,1,m) rep(i,1,n) { tmp = (n+1)/2, tmp2 = (j-1)*n; if(j&1) { if(i==1) ans1 = num[(n&1) ? (n-1) : n][j]; else { if(i <= tmp+1) ans1 = num[2*(i-1)-1][j]; else ans1 = num[(i-tmp-1)*2][j]; } } else { if(i <= tmp) ans1 = num[2*i-1][j]; else ans1 = num[(i-tmp)*2][j]; } num2[i][j] = ans1; } rep(i,1,n) rep(j,1,m) printf("%d%c", num2[i][j], " "[j==m]); } return 0; }