题目连接:http://ace.delos.com/usacogate
题目大意:有一种八位的序列,上下各四个。初始序列为
1 2 3 4
8 7 6 5,
有A,B,C,三种变换:
A:交换上下对应的数字;
B:上下两行各自向右移一位;
C:中间四个数向顺时针方向移一位。
A: |
| B: |
| C: |
|
思路:hash+bfs。从这题学到求全排列1...n的hash值的方法:
for i=0 to n-1 ,
t=0,
对于每一位, j= i+1 to n-1 ,
if(a[j] < a[i]) t++;
sum+=t*fac[7-i];//fac[i] = i!;
return ++sum;
此题要求输出路径比较蛋疼,因此又学到了一种记录路径的方法,用二维数组path[][]:path[k][0]=m表示状态k的前一状态是m;path[k][1]=i表示k是由状态m经过i变换得到的。
/*
ID: czq1992
LANG: C++
TASK: msquare
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <stdlib.h>
#include <queue>
using namespace std;
int a[10];//目标序列
int abc[3][8]={{8,7,6,5,4,3,2,1}, // A
{4,1,2,3,6,7,8,5},// B
{1,7,2,4,5,3,6,8},// C
};
struct node
{
int s[10];
};
//int ans[100][200];
queue<node> q;
bool vis[40500];
int path[40500][3];
int ans[40500];
int fac[10]={1,1,2,6,24,120,720,5040};//阶乘
int hash(int ar[])
{
int i,j,sum=1,t;
for(i=0;i<7;i++)
{
for(j=i+1,t=0;j<8;j++)
{
if(ar[j]<ar[i]) t++;
}
sum+=t*fac[7-i];
}
//cout<<sum<<endl;
return sum;
}
bool check(int ar[])//判断是否达到目标序列
{
int i;
for(i=0;i<8;i++)
{
if(a[i]!=ar[i]) return false;
}
return true;
}
void bfs()
{
int j,m=0,i,k,cnt=0;
node n1,n2,temp;
for(i=0;i<8;i++)n1.s[i]=i+1;
q.push(n1);
path[1][0]=-1;path[1][1]=0;
vis[1]=1;
while(!q.empty())
{
// cnt++;
// cout<<cnt<<endl;
n2=q.front();q.pop();
m=hash(n2.s);
if(check(n2.s)) break;
for(i=0;i<3;i++)
{
for(j=0;j<8;j++)
{
temp.s[j]=n2.s[abc[i][j]-1];
}
// for(k=0;k<8;k++)cout<<temp.s[k];
// cout<<endl;
k=hash(temp.s);
//cout<<k<<endl;
if(!vis[k])
{
q.push(temp);
vis[k]=1;
path[k][0]=m;
path[k][1]=i;
// cout<<"*"<<i<<endl;
}
}
}
//cout<<"ok\n";
cnt=0;
while(path[m][0]!=-1)
{
ans[cnt]=path[m][1];
m=path[m][0];
cnt++;
}
cout<<cnt<<endl;
for(i=cnt-1;i>=0;i--)//cout<<ans[i];
cout<<(char)(ans[i]+'A');
cout<<endl;
}
int main()
{
int i,j,f[10]={1,2,3,4,5,6,7,8};
freopen("msquare.in", "r", stdin);
freopen("msquare.out", "w", stdout);
for(i=0;i<8;i++) {cin>>a[i];}
memset(path,-1,sizeof(path));
memset(vis,0,sizeof(vis));
bfs();
return 0;
}
/*
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.000 secs, 4040 KB]
Test 2: TEST OK [0.000 secs, 4040 KB]
Test 3: TEST OK [0.000 secs, 4040 KB]
Test 4: TEST OK [0.000 secs, 4040 KB]
Test 5: TEST OK [0.011 secs, 4040 KB]
Test 6: TEST OK [0.022 secs, 4040 KB]
Test 7: TEST OK [0.032 secs, 4040 KB]
Test 8: TEST OK [0.043 secs, 4040 KB]
All tests OK.
Here are the test data inputs:
------- test 1 ----
2 6 8 4 5 7 3 1
------- test 2 ----
1 2 3 4 5 6 7 8
------- test 3 ----
6 7 4 1 8 5 2 3
------- test 4 ----
5 1 2 4 3 7 8 6
------- test 5 ----
6 1 5 4 3 2 7 8
------- test 6 ----
4 1 2 3 5 8 7 6
------- test 7 ----
3 4 2 1 5 6 7 8
------- test 8 ----
4 3 1 2 5 6 7 8
Keep up the good work!
*/