题意:给一个n行m列的矩阵,原矩阵按数字顺序从第一行开始向后填充,寻找一种方案使得原矩阵中相邻的数字在新矩阵中都不相邻。
分析:没有什么技术含量的一道构造题,试试就可以发现方案,很多人是用随机化过的这道题,但是对速度要求较高。比较稳定的方法是分两行或三行叉开放置,并且在第二行放置的时候先放两个最大的再按顺序放,例如:
可以转化为
可以转化为
只需要用合理的排列顺序就可以处理好行列大于3的所有情况
还需要特判1行、1*1、3*3的特殊情况,其他情况都无法成立。当然还有其他很多种排列方式,为了答案稳定,写的比较繁琐分了n<m和n>m,大多数代码基本都是复制粘贴,题目也没有什么算法,中间有很多地方可以优化。
代码:
1 #define _CRT_SECURE_NO_DEPRECATE 2 #pragma comment(linker, "/STACK:102400000,102400000") 3 #include<iostream> 4 #include<cstdio> 5 #include<fstream> 6 #include<iomanip> 7 #include<algorithm> 8 #include<cmath> 9 #include<deque> 10 #include<vector> 11 #include<bitset> 12 #include<queue> 13 #include<string> 14 #include<cstring> 15 #include<map> 16 #include<stack> 17 #include<set> 18 #include<functional> 19 #define pii pair<int, int> 20 #define mod 1000000007 21 #define mp make_pair 22 #define pi acos(-1) 23 #define eps 0.00000001 24 #define mst(a,i) memset(a,i,sizeof(a)) 25 #define all(n) n.begin(),n.end() 26 #define lson(x) ((x<<1)) 27 #define rson(x) ((x<<1)|1) 28 #define inf 0x3f3f3f3f 29 typedef long long ll; 30 typedef unsigned long long ull; 31 using namespace std; 32 const int maxn = 1e5 + 5; 33 vector<int>a[maxn]; 34 vector<int>ans[maxn]; 35 int n, m, cas = 0; 36 37 void change2(int t) 38 { 39 ans[t].resize(m+1); 40 ans[t + 1].resize(m+1); 41 for (int i = 1; i <= m; ++i) 42 { 43 if (i & 1)ans[t][i] = a[t][i]; 44 else ans[t + 1][i] = a[t][i]; 45 } 46 ans[t][2] = a[t + 1][m]; 47 ans[t + 1][1] = a[t + 1][m - 1]; 48 for (int i = 3; i <= m; ++i) 49 { 50 if (i & 1)ans[t + 1][i] = a[t+1][i-2]; 51 else ans[t][i] = a[t + 1][i-2]; 52 } 53 } 54 55 void change3(int t) 56 { 57 ans[t].resize(m+1); 58 ans[t + 1].resize(m+1); 59 ans[t + 2].resize(m+1); 60 for (int i = 1; i <= m; ++i) 61 { 62 if (i & 1)ans[t][i] = a[t][i]; 63 else ans[t + 2][i] = a[t][i]; 64 } 65 ans[t][2] = a[t + 1][m]; 66 ans[t + 1][1] = a[t + 1][m - 1]; 67 for (int i = 3; i <= m; ++i) 68 { 69 if (i & 1)ans[t + 1][i] = a[t + 1][i - 2]; 70 else ans[t][i] = a[t + 1][i - 2]; 71 } 72 for (int i = 1; i <= m; ++i) 73 { 74 if (i & 1)ans[t+2][i] = a[t + 2][i]; 75 else ans[t + 1][i] = a[t + 2][i]; 76 } 77 } 78 79 void change1(int t) 80 { 81 ans[t].push_back(123); 82 for (int i = 1; i <= m; ++i) 83 { 84 if ((i & 1) == cas) 85 ans[t].push_back(a[t][i]); 86 } 87 88 for (int i = 1; i <= m; ++i) 89 { 90 if ((i & 1) == (cas^1)) 91 ans[t].push_back(a[t][i]); 92 } 93 } 94 95 int main() 96 { 97 ios::sync_with_stdio(false); 98 cin.tie(0); cout.tie(0); 99 int i, j, k; 100 cin >> n >> m; 101 if (n == 3 && m == 3) 102 { 103 cout << "YES" << endl; 104 cout << "1 8 3" << endl; 105 cout << "9 2 4" << endl; 106 cout << "5 7 6" << endl; 107 return 0; 108 } 109 if (n == 1 && m == 1) 110 { 111 cout << "YES" << endl; 112 cout << "1" << endl; 113 return 0; 114 } 115 if (n <= 2 && m <= 2) { cout << "NO" << endl; return 0; } 116 if ((n == 1 && m <= 3) || (m == 1 && n == 3) || (n + m == 5 && n != 1 && m != 1)) { cout << "NO" << endl; return 0; } 117 if (n <= m) 118 { 119 for (int i = 1; i <= n; ++i) 120 { 121 a[i].push_back(123); 122 for (int j = 1; j <= m; ++j) 123 a[i].push_back((i - 1)*m + j); 124 } 125 if (n != 1) 126 { 127 if (n % 2 == 0) 128 { 129 for (int i = 1; i <= n; i += 2) 130 change2(i); 131 } 132 else 133 { 134 for (int i = 1; i <= n - 3; i += 2) 135 change2(i); 136 change3(n - 2); 137 } 138 } 139 else change1(1); 140 cout << "YES" << endl; 141 for (int i = 1; i <= n; ++i) 142 { 143 for (int j = 1; j <= m; ++j) 144 cout << ans[i][j] << " "; 145 cout << endl; 146 } 147 } 148 else 149 { 150 int cnt = 1; 151 swap(m, n); 152 for (int i = 1; i <= n; ++i)a[i].push_back(23); 153 for (int i = 1; i <= m; ++i) 154 for (int j = 1; j <= n; ++j) 155 a[j].push_back(cnt++); 156 if (n != 1) 157 { 158 if (n % 2 == 0) 159 { 160 for (int i = 1; i <= n; i += 2) 161 change2(i); 162 } 163 else 164 { 165 for (int i = 1; i <= n - 3; i += 2) 166 change2(i); 167 change3(n - 2); 168 } 169 } 170 else change1(1); 171 cout << "YES" << endl; 172 for (int i = 1; i <= m; ++i) 173 { 174 for (int j = 1; j <= n; ++j) 175 cout << ans[j][i] << " "; 176 cout << endl; 177 } 178 } 179 return 0; 180 }