如题,使用枚举的方式,但有些可能可以通过一定条件否决掉从而减少判断次数
拨钟问题
注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
有9个时钟,排成一个3*3的矩阵。
|-------| |-------| |-------| | | | | | | | |---O | |---O | | O | | | | | | | |-------| |-------| |-------| A B C |-------| |-------| |-------| | | | | | | | O | | O | | O | | | | | | | | | | |-------| |-------| |-------| D E F |-------| |-------| |-------| | | | | | | | O | | O---| | O | | | | | | | | | |-------| |-------| |-------| G H I (图 1)
现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
移动 影响的时钟 1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI (图 2)
输入
从标准输入设备读入9个整数,表示各时钟指针的起始位置。0=12点、1=3点、2=6点、3=9点。
输出
输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号大小,输出结果。
样例输入
3 3 0 2 2 2 2 1 2
样例输出
4 5 8 9
</pre><pre name="code" class="cpp">#include <stdio.h>
int site[10]; //site[1]-site[9]对应9个钟的状态
//A B C D E F G H I
//const int move1[]={1,1,0,1,1,0,0,0,0}; //i1
//const int move2[]={1,1,1,0,0,0,0,0,0}; //i2
//const int move3[]={0,1,1,0,1,1,0,0,0}; //i3
//const int move4[]={1,0,0,1,0,0,1,0,0}; //i4
//const int move5[]={0,1,0,1,1,1,0,1,0}; //i5
//const int move6[]={0,0,1,0,0,1,0,0,1}; //i6
//const int move7[]={0,0,0,1,1,0,1,1,0}; //i7
//const int move8[]={0,0,0,0,0,0,1,1,1}; //i8
//const int move9[]={0,0,0,0,1,1,0,1,1}; //i9
//A 1 2 4 钟A只能被i1、i2、i4三个拨动改变,所以当钟A不为0时,显然1、2、4不能同时为0,以此判断跳过一些不必要的枚举
//B 1 2 3 5
//C 2 3 6
//D 1 4 5 7
//E 1 3 5 7 9
//F 3 5 6 9
//G 4 7 8
//H 5 7 8 9
//I 6 8 9
int main(void){
char tmp;
int i1,i2,i3,i4,i5,i6,i7,i8,i9;
int station[10]={0};
int sum=50;
site[0]=0;
for(int m=0;m<3;m++){
for(int n=0;n<3;n++)
//scanf_s("%d",&site[3*m+n+1],1);
//scanf_s("%c",&tmp,1);
scanf("%d",&site[3*m+n+1]);
scanf("%c",&tmp);
}
for(i1=0;i1<4;i1++){
for(i2=0;i2<4;i2++)
for(i3=0;i3<4;i3++)
for(i4=0;i4<4;i4++){
if(site[1]!=0 && i1==0 && i2==0 && i4==0) //A
continue;
for(i5=0;i5<4;i5++){
if(site[2]!=0 && i1==0 && i2==0 && i3==0 && i5==0)//B
continue;
for(i6=0;i6<4;i6++){
if(site[3]!=0 && i2==0 && i3==0 && i6==0)//C
continue;
for(i7=0;i7<4;i7++){
if(site[4]!=0 && i1==0 && i4==0 && i5==0 && i7==0)//D
continue;
for(i8=0;i8<4;i8++){
if(site[7]!=0 &&i4==0 && i7==0 && i8==0)//G
continue;
for(i9=0;i9<4;i9++){
if(site[5]!=0 &&i1==0 && i3==0 && i5==0 && i7==0 && i9==0)//E
continue;
if(site[6]!=0 && i3==0 && i5==0 && i6==0 && i9==0)//F
continue;
if(site[8]!=0 && i5==0 && i7==0 && i8==0 && i9==0)//H
continue;
if(site[9]!=0 && i6==0 && i8==0 && i9==0)//I
continue;
if((0==(site[1]+i1+i2+i4)%4) && (0==(site[2]+i1+i2+i3+i5)%4) && (0==(site[3]+i2+i3+i6)%4)
&& (0==(site[4]+i1+i4+i5+i7)%4) && (0==(site[5]+i1+i3+i5+i7+i9)%4) && (0==(site[6]+i3+i5+i6+i9)%4)
&& (0==(site[7]+i4+i7+i8)%4) && (0==(site[8]+i5+i7+i8+i9)%4) && (0==(site[9]+i6+i8+i9)%4)){
//printf("%d,%d,%d,%d,%d,%d,%d,%d,%d",i1,i2,i3,i4,i5,i6,i7,i8,i9);
//printf("\n");
if(sum>i1+i2+i3+i4+i5+i6+i7+i8+i9){
sum=i1+i2+i3+i4+i5+i6+i7+i8+i9;
station[1]=i1;
station[2]=i2;
station[3]=i3;
station[4]=i4;
station[5]=i5;
station[6]=i6;
station[7]=i7;
station[8]=i8;
station[9]=i9;
}
}
}
}
}
}
}
}
}
if(sum!=50)
for(int m=1;m<10;m++){
while(station[m]!=0){
printf("%d ",m);
station[m]--;
}
}
printf("\n");
return 0;
}