Topcoder SRM 618 Div2 --900

题意:给定两个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;
    }
};
View Code
原文地址:https://www.cnblogs.com/whatbeg/p/3688660.html