B - Unbalanced Squares -- 回溯
B - Unbalanced Squares
https://atcoder.jp/contests/arc142/tasks/arc142_b
思路
按照第一行,第二行, ......, 第n行的顺序,将所有元素排成一行
X11, X12, ...., X1N, X21, X22, ...., X2N, ............., XN1, XN2, ....., XNN
对于XIJ, 枚举所有可能值, 对于每一个值确定后, 递归调用对后一个元素进行枚举, 枚举过程中,构成了周边元素完备包围, 则检查周边元素的合法性,如果合法则进入下一个元素进行枚举, 如果不合法,则回溯到上一个元素。
此方法比较耗时,不能通过测试。
Code
#include <bits/stdc++.h> #include <iostream> #include <limits.h> #include <math.h> #include <vector> #include <set> using namespace std; /* https://atcoder.jp/contests/arc142/tasks/arc142_b */ int n, n2; int sq[501][501] = {{0}}; bool used[250008] = {false}; bool check(int i, int j){ if(i < 1 || i > n){ return false; } if(j < 1 || j > n){ return false; } int pv = sq[i][j]; vector<int> adjs; for(int k=-1; k<=1; k++){ int x = i + k; if (x < 1 || x > n){ continue; } for(int l=-1; l<=1; l++){ int y = j + l; if (y < 1 || y > n){ continue; } if(i==x && j==y){ continue; } adjs.push_back(sq[x][y]); } } int size = adjs.size(); int lown = 0; int upn = 0; for(int m=0; m<size; m++){ if(adjs[m] > pv){ upn++; } else if (adjs[m] < pv){ lown++; } } if(lown != upn){ return true; } return false; } bool check_by_trigger(int i, int j){ // check error if (i > 1){ if(j > 1){ // i-1, j-1 if(!check(i-1, j-1)){ return false; } // j == n if (j == n) { if (!check(i-1, j)){ return false; } } // i == n if(i == n) { if(!check(i, j - 1)){ return false; } } // i==n j==n if(i==n && j==n){ if(!check(i, j)){ return false; } } } } return true; } bool backtracking(int i, int j){ // cout << "i=" << i << " j=" << j << endl; if(i==n+1 && j==1){ // print sq for(int k=1; k<=n; k++){ for(int l=1; l<=n; l++){ cout << sq[k][l] << " "; } cout << endl; } return true; } for(int k=1; k<=n2; k++){ if(used[k] == false){ sq[i][j] = k; if(!check_by_trigger(i, j)){ continue; } used[k] = true; if(j == n){ i ++; j = 1; } else { j ++; } bool ret = backtracking(i, j); // cout << "ret = " << ret << endl; if(ret == true){ return true; } if(j == 1){ i--; j = n; } else { j --; } used[k] = false; } } return false; } int main() { cin >> n; n2 = n*n; backtracking(1, 1); return 0; }
reference:
https://www.geeksforgeeks.org/backtracking-to-find-all-subsets/
出处:http://www.cnblogs.com/lightsong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。