UVALive

来源:互联网 发布:新手怎么样开淘宝网店 编辑:程序博客网 时间:2024/06/03 22:19

其实,,,不管二维三维的这类问题,本质都是一个置换群的对换问题

一置换中的一个长度为k的循环,至少需要k-1次对换才能恢复

对换有个性质就是,一个对换不管变奇偶性都是相同的

我们来看这道题,,其实移动一次0的,,就相当于一个对换,,

我们先将这个三维n数码化为置换,找出有w个循环,那么就说明至少需要对换n*n*n-w次,

再看0到最终位置最小步数x

如果x和n*n*n-x同奇偶性,就说明2个置换能通过对换互相转换,,,恩

#include<iostream>#include<cstdio>#include<math.h>#include<algorithm>#include<map>#include<set>#include<bitset>#include<stack>#include<queue>#include<string.h>#include<string>#include<cstring>#include<vector>#include<time.h>#include<stdlib.h>using namespace std;#define INF 0x3f3f3f3f#define INFLL 0x3f3f3f3f3f3f3f3f#define FIN freopen("input.txt","r",stdin)#define mem(x,y) memset(x,y,sizeof(x))typedef unsigned long long ULL;typedef long long LL;#define fuck(x) cout<<x<<endl;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef pair<pair<int,int>,int> PIII;typedef pair<int,int> PII;const double eps=1e-5;const int MX=1e6+5;const int P=9973;int n,w[MX];bool vis[MX];namespace IO{const int MX = 4e7;char buf[MX];int c, sz;void begin(){    c = 0;    sz = fread(buf, 1, MX, stdin);}inline bool read(int &t){    while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;    if(c >= sz) return false;    bool flag = 0;    if(buf[c] == '-') flag = 1, c++;    for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';    if(flag) t = -t;    return true;}}int main(){    IO::begin();    int T;    IO::read(T);    while(T--)    {        IO::read(n);        int pp=0;        for(int z=0; z<n; z++)            for(int y=0; y<n; y++)                for(int x=0; x<n; x++)                {                    int t;                    IO::read(t);                    //cout<<t<<endl;                    if(t==0)                    {                        pp=abs(n-1-x)+abs(n-1-y)+abs(n-1-z);                    }                    if(x==n-1&&y==n-1&&z==n-1)w[0]=t;                    else w[x+1+y*n+z*n*n]=t;                }        // cout<<pp<<endl;        int up=n*n*n,cnt=0;        for(int i=0; i<up; i++)vis[i]=0;        //for(int i=0; i<up; i++)cout<<w[i]<<" ";cout<<endl;        for(int i=0; i<up; i++)            if(vis[i]==0)            {                cnt++;                int now=w[i];                vis[i]=1;                while(now!=i)                {                    vis[now]=1;                    now=w[now];                }            }        //cout<<cnt<<endl;        if((pp+n-cnt)&1)puts("Puzzle is unsolvable.");        else puts("Puzzle can be solved.");    }    return 0;}


原创粉丝点击