题意:
给你一个N * M 的表,第i行j列的数是 (i - 1) * m + j,现在要重新安排数的位置,问你有没有一种方案使得原来相邻的数现在不相邻。
题解:
随机乱搞。
给了两秒,我们设置程序执行了1.9秒时退出随机,输出NO。
while (clock() < 1.9 * CLOCKS_PER_SEC)
一开始直接用random_suffle,暴力判断当前是否可行,如果不可行就continue。但这样搜索正解太慢,wa了。
然后我想,每次random_suffle之后都要O(n * m)判断, 如果当前只差了几个数位置不对,没必要重新random_suffle。
如果当前位置不可行,那么我们继续和后面的位置rand() 100次交换,如果还是不行,那再 random_shuffle。
然后就A了。。。
至于为什么可以随机搞,大概因为答案很多吧,要搜索到还是很容易的。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <bitset>
#include <map>
#include <vector>
#include <stack>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <ctime>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif
#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, int> pii;
const ll MOD = 1e9 + 7;
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;
int a[MAXN];
int n, m;
int check (int i) {
if (i % m != 0) if (abs (a[i] - a[i - 1]) == 1 || abs (a[i] - a[i - 1]) == m) return true;
if (i >= m) if (abs (a[i] - a[i - m]) == 1 || abs (a[i] - a[i - m]) == m) return true;
return 0;
}
int main() {
#ifdef LOCAL
freopen ("input.txt", "r", stdin);
#endif
scanf ("%d %d", &n, &m);
for (int i = 0; i < n * m; i++) a[i] = i + 1;
int ok = 0;
while (clock() < 1.9 * CLOCKS_PER_SEC) {
random_shuffle (a, a + n * m);
int f = 0;
for (int i = 0; i < n * m; i++) {
int cnt = 0;
while (check (i) && cnt <= 100) {
if (i < n * m - 1) swap (a[i], a[rand() % (n * m - i - 1) + i + 1]);
else cnt = INF;
cnt++;
}
if (cnt > 100) {
f = 1;
break;
}
}
if (f) continue;
ok = 1;
puts ("YES");
for (int i = 1; i <= n; i++) {
for (int j = 0; j < m; j++)
printf ("%d ", a[ (i - 1) * m + j]);
puts ("");
}
break;
}
if (!ok) puts ("NO");
return 0;
}