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

 

你可能感兴趣的:(topcoder)