1045六數碼(廣搜)
1045.六數碼問題
時限:1000ms 記憶體限制:10000K 總時限:3000ms
描述
現有一兩行三列的表格如下: A B C D E F 把1、2、3、4、5、6六個數字分別填入A、B、C、D、E、F格子中,每個格子一個數字且各不相同。每種不同的填法稱為一種佈局。如下: 1 3 5 2 4 6 佈局1 2 5 6 4 3 1 佈局2 定義α變換如下:把A格中的數字放入B格,把B格中的數字放入E格,把E格中的數字放入D格,把D格中的數字放入A格。 定義β變換如下:把B格中的數字放入C格,把C格中的數字放入F格,把F格中的數字放入E格,把E格中的數字放入B格。 問:對於給定的佈局,可否通過有限次的α變換和β變換變成下面的目標佈局: 1 2 3 4 5 6 目標佈局
輸入
本題有多個測例,每行一個,以EOF為輸入結束標誌。每個測例的輸入是1到6這六個數字的一個排列,空格隔開,表示初始佈局ABCDEF格中依次填入的數字。
輸出
每個輸出佔一行。可以轉換的,列印Yes;不可以轉換的,列印No。
輸入樣例
1 3 5 2 4 6 2 5 6 4 3 1
輸出樣例
No Yes
程式碼:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int book[654321]; int a[2][3]; int b[2][3]; int c[2][3]; queue<int>q; int moveto1(int x) { memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); int i,j; int sum2=0; for(i=1;i>=0;i--) { for(j=2;j>=0;j--) { b[i][j]=x%10; x=x/10; } } c[0][1]=b[0][0]; c[1][1]=b[0][1]; c[1][0]=b[1][1]; c[0][0]=b[1][0]; c[0][2]=b[0][2]; c[1][2]=b[1][2]; for(int i=0;i<2;i++) for(int j=0;j<3;j++) { sum2=sum2*10+c[i][j]; } return sum2; } int moveto2(int x) { memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); int i,j; int sum2=0; for(i=1;i>=0;i--) { for(j=2;j>=0;j--) { b[i][j]=x%10; x=x/10; } } c[0][1]=b[1][1]; c[1][1]=b[1][2]; c[0][2]=b[0][1]; c[1][2]=b[0][2]; c[0][0]=b[0][0]; c[1][0]=b[1][0]; for(int i=0;i<2;i++) for(int j=0;j<3;j++) { sum2=sum2*10+c[i][j]; } return sum2; } int bfs() { int x,y; while(!q.empty()) { x=q.front(); q.pop(); if(x==123456)return 1; y=moveto1(x); if(y==123456)return 1; else { if(book[y]==0) { q.push(y); book[y]=1; } } y=moveto2(x); if(y==123456)return 1; else { if(book[y]==0) { q.push(y); book[y]=1; } } } return 0; } int main() { int s; while(cin>>s) { while(!q.empty()) { q.pop(); } memset(book,0,sizeof(book)); memset(a,0,sizeof(a)); int sum1=0; int flag; a[0][0]=s; cin>>a[0][1]>>a[0][2]; for(int j=0;j<3;j++) { cin>>a[1][j]; } for(int i=0;i<2;i++) for(int j=0;j<3;j++) { sum1=sum1*10+a[i][j]; } q.push(sum1); book[sum1]=1; flag=bfs(); if(flag==1)cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }