You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

修复建议

  1. 把所有索引合法判断中的>0全部改为>=0,修正相邻检查逻辑。
  2. 交换完成后立刻添加break跳出两层(l,m)循环,避免多余交换。
  3. 这道题可以使用更简单的构造方法:将1~n²的所有奇数按顺序排列,再拼接所有偶数,按行优先填入二维数组即可,不需要复杂的交换逻辑。比如n=3时序列为1,3,5,7,9,2,4,6,8,填入后自动满足相邻元素差不为1的要求。

内容的提问来源于stack exchange,提问作者Benjamin Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 07:45:03