C++求解Codeforces1520C时boolean变量异常变化交换结果错误问题
#include<iostream> #include <vector> #include <string> using namespace std; int main() { int t, n; cin >> t; for (int i = 0; i < t; i++) { cin >> n; vector<vector<int>> numbers; for (int k = 1; k < n * n; k += n) { vector<int> temp; for (int j = 0; j < n; j++) { temp.push_back(k + j); } numbers.push_back(temp); } for (int j = 0; j < numbers.size(); j++) //row for (int k = 0; k < numbers.size(); k++) { //column bool adjacent = false; if (j - 1 > 0) if (abs(numbers[j][k] - numbers[j - 1][k]) == 1) adjacent = true; if (j + 1 < numbers.size()) if (abs(numbers[j][k] - numbers[j + 1][k]) == 1) adjacent = true; if (k - 1 > 0) if (abs(numbers[j][k] - numbers[j][k - 1]) == 1) adjacent = true; if (k + 1 < numbers.size()) if (abs(numbers[j][k] - numbers[j][k + 1]) == 1) adjacent = true; if (adjacent) for (int l = 0; l < numbers.size(); l++) for (int m = 0; m < numbers.size(); m++) { bool adjacent2 = false, adjacent3 = false; if (j - 1 > 0) if (abs(numbers[l][m] - numbers[j - 1][k]) == 1) adjacent2 = true; if (j + 1 < numbers.size()) if (abs(numbers[l][m] - numbers[j + 1][k]) == 1) adjacent2 = true; if (k - 1 > 0) if (abs(numbers[l][m] - numbers[j][k - 1]) == 1) adjacent2 = true; if (k + 1 < numbers.size()) if (abs(numbers[l][m] - numbers[j][k + 1]) == 1) { adjacent2 = true; cout << "hi " << adjacent2 << endl; //HERE } if (!adjacent2) { cout << adjacent2 << endl; if (l - 1 > 0) if (abs(numbers[j][k] - numbers[l - 1][m]) == 1) adjacent3 = true; if (l + 1 < numbers.size()) if (abs(numbers[j][k] - numbers[l + 1][m]) == 1) adjacent3 = true; if (m - 1 > 0) if (abs(numbers[j][k] - numbers[l][m - 1]) == 1) adjacent3 = true; if (m + 1 < numbers.size()) if (abs(numbers[j][k] - numbers[l][m + 1]) == 1) adjacent3 = true; if (!adjacent3) { int temp = numbers[j][k]; numbers[j][k] = numbers[l][m]; numbers[l][m] = temp; } } } } if (n > 2) for (auto x : numbers) { for (int y : x) { cout << y << " "; } cout << endl; } else if (n == 1) cout << 1 << endl; else cout << -1 << endl; } }
问题根因
- 边界判断逻辑错误:所有检查索引是否合法的条件都写为
>0,但数组索引从0开始,正确的合法判断应该是>=0。比如if (j - 1 > 0)只有j>=2时才会检查上方元素,第一行、第二行的上方相邻判断直接失效,同理第一列的左侧相邻判断也全部失效,初始的相邻检查逻辑本身就存在错误。 - 变量生命周期混淆:
adjacent2是定义在(l,m)循环内部的局部变量,每一轮(l,m)迭代都会重新初始化为false。你在HERE位置打印的是某一轮迭代中adjacent2为true的结果,而触发if(!adjacent2)的是另一轮迭代的变量,两次不属于同一个生命周期,不存在未修改就变化的问题,只是你把不同迭代的输出混淆了。 - 交换逻辑缺少终止:找到符合要求的交换元素完成交换后,没有break跳出(l,m)循环,程序会继续遍历后续元素,触发多次多余交换,甚至把刚修改正确的位置再次打乱。你遇到的1和2互换的问题,就是因为遍历(l,m)时先遇到了(0,1)位置的2,满足交换条件就直接完成了交换,还没遍历到你期望的(1,0)位置的4。
修复建议
- 把所有索引合法判断中的
>0全部改为>=0,修正相邻检查逻辑。 - 交换完成后立刻添加break跳出两层(l,m)循环,避免多余交换。
- 这道题可以使用更简单的构造方法:将1~n²的所有奇数按顺序排列,再拼接所有偶数,按行优先填入二维数组即可,不需要复杂的交换逻辑。比如n=3时序列为
1,3,5,7,9,2,4,6,8,填入后自动满足相邻元素差不为1的要求。
内容的提问来源于stack exchange,提问作者Benjamin Chen
相关产品推荐
相关产品推荐

