pku 2286 The Rotation Game
题目地址:http://acm.pku.edu.cn/JudgeOnline/problem?id=2286
题目大意:
给出一个"#"字型的图,如同行李箱上的滑轮锁一样,可以滑动这个“#”字图的行,列,有8种操作方式,问在操作次数最少的情况下,字典序最小的操作序列是多少才能使"#"字型中间的“口”的数字完全一样,IDA*。
详细分析:
待填坑。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
char s[105];
int Map[9][9];
int num[5];
char path[10000000];
int cnt = 0;
int Matrix_input[8][8] = { //辅助输入的数组
{0,0,0,0,0,0,0,0},
{2,3,5,0,0,0,0,0},
{2,3,5,0,0,0,0,0},
{7,1,2,3,4,5,6,7},
{2,3,5,0,0,0,0,0},
{7,1,2,3,4,5,6,7},
{2,3,5,0,0,0,0,0},
{2,3,5,0,0,0,0,0}
};
char Matrix_rota[8][3] ={ //辅助变换的数组
{'3','c','f'},//A 0
{'5','c','f'},//B 1
{'3','l','b'},//C 2
{'5','l','b'},//D 3
{'5','c','b'},//E 4
{'3','c','b'},//F 5
{'5','l','f'},//G 6
{'3','l','f'}//H 7
};
char opt[8] ={'A','B','C','D','E','F','G','H'};
int back_opt[8]={5,4,7,6,1,0,3,2};
int h()
{
int maxx= -1;
memset(num,0,sizeof(num));
for(int i = 3 ; i <= 5 ;i++ )
for(int j= 3; j<= 5; j++)
{
if(!( i==4 && j== 4))
num[Map[i][j]]++;
maxx = max(maxx, num[Map[i][j]]);
}
return 8 -maxx; //至少还要再往下搜多少层
}
void Rota(int a)
{
int pos = Matrix_rota[a][0] -'0';
char type = Matrix_rota[a][1];
char dirc = Matrix_rota[a][2];
if(type =='l')
{
if(dirc == 'f')
{
for(int i = 1 ;i <= 7; i++)
Map[pos][i - 1] = Map[pos][i];
Map[pos][7] = Map[pos][0];
}
if(dirc == 'b')
{
for(int i = 7 ;i >=1; i--)
Map[pos][i + 1] = Map[pos][i];
Map[pos][1] = Map[pos][8];
}
}
if( type == 'c' )
{
if( dirc == 'f' )
{
for(int i = 1 ;i <= 7; i++)
Map[i - 1][pos] = Map[i][pos];
Map[7][pos] = Map[0][pos];
}
if(dirc == 'b')
{
for(int i = 7 ;i >=1 ; i--)
Map[i + 1][pos] = Map[i][pos];
Map[1][pos] = Map[8][pos];
}
}
return ;
}
int DFS(int deep, int n)
{
if( h() == 0 )
return 1;
if(deep + h() > n)
return 0;
for(int i = 0 ; i< 8 ;i++)
{
Rota(i);
path[ cnt++ ] = opt[i];
if(DFS(deep + 1, n))
return 1;
cnt--;
Rota(back_opt[i]);
}
return 0;
}
int main()
{
while(gets(s))
{
cnt = 0;
if( strlen(s) ==1 &&s[0] == '0' )
break;
int index = 0 ,line = 1;
for(int i = 0 ;i < strlen(s); i++)
{
if(s[i]!= ' ')
{
index++ ;
if(index <= Matrix_input[line][0])
Map[line][Matrix_input[line][index]] = s[i] -'0';
if(index == Matrix_input[line][0])
{
index -= Matrix_input[line][0];
line++;
}
}
}
for(int i = 1 ; ; i++)
if(DFS(0,i))
break;
if(cnt )
{
for(int i = 0 ; i < cnt ;i++ )
cout << path[i];
cout << endl;
}
else
cout << "No moves needed" << endl;
cout << Map[3][3] << endl;
//cout << h() << endl;
/*
for(int i = 0 ;i < 8 ;i++)
{
Rota(i);
for(int j = 1; j <=7; j++)
{
for(int k = 1 ;k <=7 ;k++)
cout << Map[j][k];
cout << endl;
}
Rota(back_opt[i]);
}
*/
}
return 0;
}