题目链接:http://poj.org/problem?id=1166
题目意思:
9只钟表排成3*3的方阵,每只钟表只能指向上、下、左、右四个位置
9种作用方式,每种使一些钟表的指针右转90°
使用这9种作用,使得所有钟表都指向正上方 (记为状态0)
求使得总作用次数最少的策略
分析:每只钟表被拨动的次数不会超过三次,因为三次后就又回到了初始状态。
代码:
#include<stdio.h>
#include<string.h>
int move[9][9]={ //记录口令对每个钟表时刻的影响
{1,1,0,1,1,0,0,0,0},
{1,1,1,0,0,0,0,0,0},
{0,1,1,0,1,1,0,0,0},
{1,0,0,1,0,0,1,0,0},
{0,1,0,1,1,1,0,1,0},
{0,0,1,0,0,1,0,0,1},
{0,0,0,1,1,0,1,1,0},
{0,0,0,0,0,0,1,1,1},
{0,0,0,0,1,1,0,1,1}
};
int num[9],tmp[9],In_dial[9];//num[i]保存指令i的作用次数
int finished;
int judge() //判断是否将所有的时刻拨到了12点
{
int i,j;
for(i=0;i<9;i++)
tmp[i]=In_dial[i];
for(i=0;i<9;i++)
for(j=0;j<9;j++)
tmp[i]=(tmp[i]+move[j][i]*num[j])%4;
for(i=0;i<9;i++)
if(tmp[i])
return 0;
return 1;
}
void output() //输出拨动的最短序列
{
int i,j;
for(i=0;i<9;i++)
for(j=0;j<num[i];j++)
printf("%d ",i+1);
printf("\n");
}
void dfs(int opration)
{
int i;
if(judge())
{
finished=1;
output();
return;
}
if(opration>=9)
return ;
for(i=0;i<4;i++)
{
num[opration]=i;
dfs(opration+1);
if(finished)
return ;
}
}
void main()
{
int i;
for(i=0;i<9;i++)
scanf("%d",&In_dial[i]);
memset(num,0,sizeof(num));
finished=0;
dfs(0);
return ;
}