题意:给定两个NxN的棋盘,每个棋盘都有一个‘车’的摆放状态,问进行若干次交换,能否使棋盘1变为棋盘2.
交换规则:每次选两个‘车’,坐标分别为(r1,c1),(r2,c2),如果r1<r2并且c1>c2,则可以将两个点分别移到(r1,c2),(r2,c1)。
做法:BFS,从状态Y1广搜,每次选两行r1,r2(r1<r2),如果满足r1行的‘车’的列c1<c2(r2行的‘车’的列),则交换,得到下一个状态点,如果不是目标态,则继续搜索,知道交换完所有状态。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <set> #include <queue> using namespace std; #define N 57 typedef vector<int> VI; int equal(VI ka,VI kb) { int len = ka.size(); for(int i=0;i<len;i++) if(ka[i] != kb[i]) return 0; return 1; } class MovingRooksDiv2 { private: public: string move(VI Y1,VI Y2) { int len = Y1.size(); string res = "Impossible"; set<VI > vis; queue<VI > que; que.push(Y1); vis.insert(Y1); while(!que.empty()) { VI now = que.front(); que.pop(); if(equal(now,Y2)) //到达目标态 { res = "Possible"; break; } for(int r1=0;r1<len;r1++) { for(int r2=r1+1;r2<len;r2++) //r1<r2 { VI v = now; if(v[r1] <= v[r2]) //不满足c1>c2 continue; swap(v[r1],v[r2]); //交换两个'车' if(!vis.count(v)) { que.push(v); vis.insert(v); } } } } return res; } };