The Clocks
IOI'94 - Day 2
Consider nine clocks arranged in a 3x3 array thusly:
|-------| |-------| |-------|
| | | | | | |
|---O | |---O | | O |
| | | | | |
|-------| |-------| |-------|
A B C
|-------| |-------| |-------|
| | | | | |
| O | | O | | O |
| | | | | | | | |
|-------| |-------| |-------|
D E F
|-------| |-------| |-------|
| | | | | |
| O | | O---| | O |
| | | | | | | |
|-------| |-------| |-------|
G H I
The goal is to find a minimal sequence of moves to return all the dials to 12 o'clock. Nine different ways to turn the dials on the clocks are supplied via a table below; each way is called a move. Select for each move a number 1 through 9 which will cause the dials of the affected clocks (see next table) to be turned 90 degrees clockwise.
Move | Affected clocks |
1 | ABDE |
2 | ABC |
3 | BCEF |
4 | ADG |
5 | BDEFH |
6 | CFI |
7 | DEGH |
8 | GHI |
9 | EFHI |
Example
Each number represents a time accoring to following table:
9 9 12 9 12 12 9 12 12 12 12 12 12 12 12
6 6 6 5 -> 9 9 9 8-> 9 9 9 4 -> 12 9 9 9-> 12 12 12
6 3 6 6 6 6 9 9 9 12 9 9 12 12 12
[But this might or might not be the `correct' answer; see below.]
PROGRAM NAME: clocks
INPUT FORMAT
Lines 1-3: | Three lines of three space-separated numbers; each number represents the start time of one clock, 3, 6, 9, or 12. The ordering of the numbers corresponds to the first example above. |
SAMPLE INPUT (file clocks.in)
9 9 12
6 6 6
6 3 6
OUTPUT FORMAT
A single line that contains a space separated list of the shortest sequence of moves (designated by numbers) which returns all the clocks to 12:00. If there is more than one solution, print the one which gives the lowest number when the moves are concatenated (e.g., 5 2 4 6 < 9 3 1 1).
SAMPLE OUTPUT (file clocks.out)
4 5 8 9
在每个状态下,其下一次旋转有9种选择,每种选择得到一个新的状态,由此,可以想到由广搜(BFS),将每次得到的不同的状态(以前没有得到)压入队列,直到搜到需要的结果,因为要输出操作步骤,在此用了两个数组,一个数组用来记录路径,一个用来记录相应路径对应的步骤。还有一个很重要的问题,就是每个状态怎样存储,时钟只有3,6,9,12;我们不妨都除以3,得到1,2,3,4;在对4取余,得到0,1,2,3,每个钟上的数字对应一位四进制数,将每个状态所对应的四进制的数转换成十进制的数,所需数组大小为4^9不会MLE。具体代码如下:
/*
ID:jinyuxu2
LANG:C++
PROG:clocks
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int x,len;
int ans[200];
int vis[270000];
int p[270000];
int a[9],b[9];
int map[9]={65536,16384,4096,1024,256,64,16,4,1};
queue<int>q;
int vis_Next(int v)
{
if(v==1)
{
a[0]=(a[0]+1)%4;
a[1]=(a[1]+1)%4;
a[3]=(a[3]+1)%4;
a[4]=(a[4]+1)%4;
}
if(v==2)
{
a[0]=(a[0]+1)%4;
a[1]=(a[1]+1)%4;
a[2]=(a[2]+1)%4;
}
if(v==3)
{
a[1]=(a[1]+1)%4;
a[2]=(a[2]+1)%4;
a[4]=(a[4]+1)%4;
a[5]=(a[5]+1)%4;
}
if(v==4)
{
a[0]=(a[0]+1)%4;
a[3]=(a[3]+1)%4;
a[6]=(a[6]+1)%4;
}
if(v==5)
{
a[1]=(a[1]+1)%4;
a[3]=(a[3]+1)%4;
a[4]=(a[4]+1)%4;
a[5]=(a[5]+1)%4;
a[7]=(a[7]+1)%4;
}
if(v==6)
{
a[2]=(a[2]+1)%4;
a[5]=(a[5]+1)%4;
a[8]=(a[8]+1)%4;
}
if(v==7)
{
a[3]=(a[3]+1)%4;
a[4]=(a[4]+1)%4;
a[6]=(a[6]+1)%4;
a[7]=(a[7]+1)%4;
}
if(v==8)
{
a[6]=(a[6]+1)%4;
a[7]=(a[7]+1)%4;
a[8]=(a[8]+1)%4;
}
if(v==9)
{
a[4]=(a[4]+1)%4;
a[5]=(a[5]+1)%4;
a[7]=(a[7]+1)%4;
a[8]=(a[8]+1)%4;
}
int sum=0;
for(int i=0;i<9;i++)
sum+=a[i]*map[i];
return sum;
}
void BFS()
{
while(!q.empty())
{
int t=q.front();
q.pop();
if(t==0)
break;
for(int i=0;i<9;i++)
b[i]=(t/map[i])%4;
for(int i=1;i<10;i++)
{
for(int j=0;j<9;j++)
a[j]=b[j];
int cnt=vis_Next(i);
if(vis[cnt]==-1)
{
p[cnt]=i;
vis[cnt]=t;
q.push(cnt);
}
}
}
}
int main()
{
freopen("clocks.in","r",stdin);
freopen("clocks.out","w",stdout);
int w;
x=0;
len=0;
for(int i=0;i<9;i++)
{
scanf("%d",&w);
w/=3;
w%=4;
x+=w*map[i];
}
memset(vis,-1,sizeof(vis));
memset(p,-1,sizeof(p));
q.push(x);
BFS();
int i=0;
while(vis[i]!=x)
{
ans[len++]=p[i];
i=vis[i];
}
ans[len]=p[i];
for(int i=len;i>0;i--)
printf("%d ",ans[i]);
printf("%d\n",ans[0]);
return 0;
}