1. 程式人生 > >洛谷P2730 魔板 Magic Squares

洛谷P2730 魔板 Magic Squares

難題 空格 hold 換上 整數 三種 txt 字符 sca

P2730 魔板 Magic Squares

題目背景

在成功地發明了魔方之後,魯比克先生發明了它的二維版本,稱作魔板。這是一張有8個大小相同的格子的魔板:

1 2 3 4

8 7 6 5

題目描述

我們知道魔板的每一個方格都有一種顏色。這8種顏色用前8個正整數來表示。可以用顏色的序列來表示一種魔板狀態,規定從魔板的左上角開始,沿順時針方向依次取出整數,構成一個顏色序列。對於上圖的魔板狀態,我們用序列(1,2,3,4,5,6,7,8)來表示。這是基本狀態。

這裏提供三種基本操作,分別用大寫字母“A”,“B”,“C”來表示(可以通過這些操作改變魔板的狀態):

“A”:交換上下兩行;

“B”:將最右邊的一列插入最左邊;

“C”:魔板中央四格作順時針旋轉。

下面是對基本狀態進行操作的示範:

A: 8 7 6 5

1 2 3 4

B: 4 1 2 3

5 8 7 6

C: 1 7 2 4

8 6 3 5

對於每種可能的狀態,這三種基本操作都可以使用。

你要編程計算用最少的基本操作完成基本狀態到目標狀態的轉換,輸出基本操作序列。

輸入輸出格式

輸入格式:

只有一行,包括8個整數,用空格分開(這些整數在範圍 1——8 之間)不換行,表示目標狀態。

輸出格式:

Line 1: 包括一個整數,表示最短操作序列的長度。

Line 2: 在字典序中最早出現的操作序列,用字符串表示,除最後一行外,每行輸出60個字符。

輸入輸出樣例

輸入樣例#1:
2 6 8 4 5 7 3 1 
輸出樣例#1:
7 
BCABCCB

說明

題目翻譯來自NOCOW。

USACO Training Section 3.2

/*
    八數碼難題那種搜索做多了,這種題也就不叫題了。。
    直接寬搜,記錄狀態直接map(hash害我無數次我才不要用),字符串直接加加減減拼組起來,我以為會超時呢。
    就是這麽暴力的方法,主意一下內存限制,隊列不要開得太大,當然循環隊列這裏用不到。
    在註意一下輸出格式,就可以A了。
*/ #include<iostream> #include<cstdio> #include<map> #include<cstring> using namespace std; map<string,bool>vis; struct node{ int fa,step; string s; char op; }cur,nxt,q[5000000]; int head=1,tail=0; string goal,start="12348765",ans; void work(int now){ if(q[now].fa==-1)return; work(q[now].fa); //printf("%c",q[now].op); ans+=q[now].op; } int main(){ //freopen("Cola.txt","r",stdin); int x; string ch; for(int i=1;i<=8;i++){ scanf("%d",&x); ch+=x+0; } goal+=ch.substr(0,4); for(int i=7;i>=4;i--)goal+=ch[i]; cur.s=start;cur.fa=-1;cur.step=0; vis[cur.s]=1; if(cur.s==goal){ printf("0"); return 0; } q[++tail]=cur; while(head<=tail){ cur=q[head]; string s=cur.s; if(cur.s==goal){ printf("%d\n",cur.step); work(head); int start=0,len=ans.length(); while(start<len){ cout<<ans.substr(start,60); start+=60; } break; } //操作A nxt.s=""; nxt.s+=s.substr(4,4);nxt.s+=s.substr(0,4); nxt.op=A;nxt.step=cur.step+1;nxt.fa=head; if(!vis[nxt.s])q[++tail]=nxt,vis[nxt.s]=1; if(nxt.s==goal){ printf("%d\n",nxt.step); work(tail); int start=0,len=ans.length(); while(start<len){ cout<<ans.substr(start,60); start+=60; } break; } //操作B nxt.s=""; nxt.s+=s[3];nxt.s+=s.substr(0,3); nxt.s+=s[7];nxt.s+=s.substr(4,3); nxt.op=B;nxt.step=cur.step+1;nxt.fa=head; if(!vis[nxt.s])q[++tail]=nxt,vis[nxt.s]=1; if(nxt.s==goal){ printf("%d\n",nxt.step); work(tail); int start=0,len=ans.length(); while(start<len){ cout<<ans.substr(start,60); start+=60; } break; } //操作C nxt.s=""; nxt.s+=s[0];nxt.s+=s[5];nxt.s+=s[1];nxt.s+=s[3];nxt.s+=s[4];nxt.s+=s[6];nxt.s+=s[2];nxt.s+=s[7]; nxt.step=cur.step+1;nxt.op=C;nxt.fa=head; if(!vis[nxt.s])q[++tail]=nxt,vis[nxt.s]=1; if(nxt.s==goal){ printf("%d\n",nxt.step); work(tail); int start=0,len=ans.length(); while(start<len){ cout<<ans.substr(start,60); start+=60; } break; } head++; } /*int sz=sizeof(q)+sizeof(vis); cout<<endl<<sz/1048576;*/ }

洛谷P2730 魔板 Magic Squares