题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2918
Tobo or not Tobo
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1062 Accepted Submission(s): 418
Problem Description
The game of Tobo is played on a plastic board designed into a 3 × 3 grid with cells numbered from 1 to 9 as shown in figure (a). The grid has four dials (labeled ``A" to ``D" in the figure.) Each dial can be rotated in 90 degrees increment in either direction. Rotating a dial causes the four cells currently adjacent to it to rotate along. For example, figure (b) shows the Tobo after rotating dial ``A" once in a clockwise direction. Figure (c) shows the Tobo in figure (b) after rotating dial ``D" once in a counterclockwise direction.
Kids love to challenge each other playing the Tobo. Starting with the arrangement shown in figure (a), (which we'll call the standard arrangement,) one kid would randomly rotate the dials, X number of times, in order to ``shuffle" the board. Another kid then tries to bring the board back to its standard arrangement, taking no more than X rotations to do so. The less rotations are needed to restore it, the better. This is where you see a business opportunity. You would like to sell these kids a program to advise them on the minimum number of steps needed to bring a Tobo back to its standard arrangement.
Kids love to challenge each other playing the Tobo. Starting with the arrangement shown in figure (a), (which we'll call the standard arrangement,) one kid would randomly rotate the dials, X number of times, in order to ``shuffle" the board. Another kid then tries to bring the board back to its standard arrangement, taking no more than X rotations to do so. The less rotations are needed to restore it, the better. This is where you see a business opportunity. You would like to sell these kids a program to advise them on the minimum number of steps needed to bring a Tobo back to its standard arrangement.
Input
Your program will be tested on one or more test cases. Each test case is specified on a line by itself. Each line is made of 10 decimal digits. Let's call the first digit Y . The remaining 9 digits are non-zeros and describe the current arrangement of the Tobo in a row-major top-down, left-to-right ordering. The first sample case corresponds to figure (c).
The last line of the input file is a sequence of 10 zeros.
The last line of the input file is a sequence of 10 zeros.
Output
For each test case, print the result using the following format:
k . R
where k is the test case number (starting at 1,) is a single space, and R is the minimum number of rotations needed to bring the Tobo back to its standard arrangement. If this can't be done in Y dials or less, then R = -1.
k . R
where k is the test case number (starting at 1,) is a single space, and R is the minimum number of rotations needed to bring the Tobo back to its standard arrangement. If this can't be done in Y dials or less, then R = -1.
Sample Input
3413569728 1165432789 0000000000
Sample Output
1. 2 2. -1
Source
Recommend
题目大意:具体没怎么读题,AC的猜测是这样的:有A、B、C、D四个按键,按下一次可以顺时针或逆时针旋转90度,变成对应的样子。最后要求输出所给的序列变成目标序列123456789最少需要移动几步。
特别注意:
1、输入的第一个数字为最多的步数,如果在所规定的步数内没有完成就直接输出-1。
2、每次最多移动四个数字,所以get_h()的最优解即为:(最少不在正确位置的字符数+3)/4。
3、最后注意输出的格式,避免PE。
详见代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
char ch[20];
char str[10][10],Map[10][10];
int want;
void init()
{
char g='1';
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
Map[i][j]=g++;
}
}
}
void move_c(int i,int j)//顺时针旋转
{
char t=str[i][j];
str[i][j]=str[i+1][j];
str[i+1][j]=str[i+1][j+1];
str[i+1][j+1]=str[i][j+1];
str[i][j+1]=t;
}
void move_e(int i,int j)//逆时针旋转
{
char t=str[i][j];
str[i][j]=str[i][j+1];
str[i][j+1]=str[i+1][j+1];
str[i+1][j+1]=str[i+1][j];
str[i+1][j]=t;
}
int get_h()
{
init();
int t=0;
int ans=0;
for (int i=0; i<3; i++)//查找最少有多少个字符不在正确的位置上
{
for (int j=0; j<3; j++)
{
if (str[i][j]!=Map[i][j])
t++;
}
}
ans=(t+3)/4;//ans表示的是最少错误字符需要走的步数
return ans;
}
bool IDA(int dep)//传过的值为已经走了的步数
{
if (dep+get_h()>want)
return false;
//cout<<" "<<get_h()<<" "<<dep<<" "<<want<<endl;
if (dep==want&&get_h()==0)
return true;
move_c(0,0);//绕着A移动
if (IDA(dep+1))
return true;
move_e(0,0);
move_e(0,0);
if (IDA(dep+1))
return true;
move_c(0,0);
move_c(0,1);//绕着B移动
if (IDA(dep+1))
return true;
move_e(0,1);
move_e(0,1);
if (IDA(dep+1))
return true;
move_c(0,1);
move_c(1,0);//绕着C移动
if (IDA(dep+1))
return true;
move_e(1,0);
move_e(1,0);
if (IDA(dep+1))
return true;
move_c(1,0);
move_c(1,1);//绕着D移动
if (IDA(dep+1))
return true;
move_e(1,1);
move_e(1,1);
if (IDA(dep+1))
return true;
move_c(1,1);
return false;
}
int main()
{
int Case=1;
while (~scanf("%s",ch))
{
int flag=0;
if (strcmp(ch,"0000000000")==0)
break;
int kk=ch[0]-'0';
int k=1;
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
str[i][j]=ch[k++];
}
}
want=0;
while (true)
{
//cout<<"want="<<want<<endl;
if (IDA(0)==true)//找到最小步数
{
flag=1;
break;
}
want++;
if (want>kk)//在规定的步数内不能实现
{
flag=0;
break;
}
}
if (flag==1)
printf ("%d. %d\n",Case++,want);
else
printf ("%d. -1\n",Case++);
}
return 0;
}