题意是给你九个只指向3,6,9,12点的钟表,让你用题目给的9种方式把所有表都拨到12点,求最少步数的操作方式。
思路是暴搜,网上说的dfs,bfs因为能力不足,无法理解。
每个钟如果拨动四次等于没拨,所以每个变换设定最多只变三次。
首先先对输入的数字进行处理,因为只有3 6 9 12,四钟情况,所以缩小变为,1 2 3 0 。
num[ i ] 表示第 i 种变换。
因为表1在变化1,2,4中才被拨,所以:tmp[ 1 ]=(a[ i ] + num[ 1 ] + num[ 2 ] + num[ 4 ] )%4 ) 。
以此类推。
代码:usaco:
/*
ID: who jay
LANG: C++
TASK: clocks
*/
#include<stdio.h>
int a[10],num[10],tmp[10];
int main()
{
freopen("clocks.in","r",stdin);
freopen("clocks.out","w",stdout);
int i,j,k;
bool flag=1;
for(i=1; i<=9; i++)
{
scanf("%d",&k);
if(k==12)
a[i]=0;
else
a[i]=k/3;
}
for(num[1]=0; num[1]<=3; num[1]++)
for(num[2]=0; num[2]<=3; num[2]++)
for(num[3]=0; num[3]<=3; num[3]++)
for(num[4]=0; num[4]<=3; num[4]++)
for(num[5]=0; num[5]<=3; num[5]++)
for(num[6]=0; num[6]<=3; num[6]++)
for(num[7]=0; num[7]<=3; num[7]++)
for(num[8]=0; num[8]<=3; num[8]++)
for(num[9]=0; num[9]<=3; num[9]++)
{
tmp[1]=(a[1]+num[1]+num[2]+num[4])%4;
tmp[2]=(a[2]+num[1]+num[2]+num[3]+num[5])%4;
tmp[3]=(a[3]+num[2]+num[3]+num[6])%4;
tmp[4]=(a[4]+num[1]+num[4]+num[5]+num[7])%4;
tmp[5]=(a[5]+num[1]+num[3]+num[5]+num[7]+num[9])%4;
tmp[6]=(a[6]+num[3]+num[5]+num[6]+num[9])%4;
tmp[7]=(a[7]+num[4]+num[7]+num[8])%4;
tmp[8]=(a[8]+num[5]+num[7]+num[8]+num[9])%4;
tmp[9]=(a[9]+num[6]+num[8]+num[9])%4;
if(tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7]+tmp[8]+tmp[9]==0)
{
for(i=1; i<=9; i++)
for(j=1; j<=num[i]; j++)
if(flag)
{
printf("%d",i);
flag=0;
}
else
printf(" %d",i);
printf("\n");
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
poj1166:
与usaco的区别就是poj直接省去了开始的转换,同解。
#include<stdio.h>
int a[10],num[10],tmp[10];
int main()
{
int i,j,k;
bool flag=1;
for(i=1; i<=9; i++)
{
scanf("%d",&a[i]);
}
for(num[1]=0; num[1]<=3; num[1]++)
for(num[2]=0; num[2]<=3; num[2]++)
for(num[3]=0; num[3]<=3; num[3]++)
for(num[4]=0; num[4]<=3; num[4]++)
for(num[5]=0; num[5]<=3; num[5]++)
for(num[6]=0; num[6]<=3; num[6]++)
for(num[7]=0; num[7]<=3; num[7]++)
for(num[8]=0; num[8]<=3; num[8]++)
for(num[9]=0; num[9]<=3; num[9]++)
{
tmp[1]=(a[1]+num[1]+num[2]+num[4])%4;
tmp[2]=(a[2]+num[1]+num[2]+num[3]+num[5])%4;
tmp[3]=(a[3]+num[2]+num[3]+num[6])%4;
tmp[4]=(a[4]+num[1]+num[4]+num[5]+num[7])%4;
tmp[5]=(a[5]+num[1]+num[3]+num[5]+num[7]+num[9])%4;
tmp[6]=(a[6]+num[3]+num[5]+num[6]+num[9])%4;
tmp[7]=(a[7]+num[4]+num[7]+num[8])%4;
tmp[8]=(a[8]+num[5]+num[7]+num[8]+num[9])%4;
tmp[9]=(a[9]+num[6]+num[8]+num[9])%4;
if(tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7]+tmp[8]+tmp[9]==0)
{
for(i=1; i<=9; i++)
for(j=1; j<=num[i]; j++)
if(flag)
{
printf("%d",i);
flag=0;
}
else
printf(" %d",i);
printf("\n");
}
}
return 0;
}
附上usaco标程中的大神写法,还没有看懂:
You can precalculate a matrix a as following:
(你可以预先计算一个如下的矩阵)
a[i][0],a[i][1],....,a[i][8] is the number of moves '1','2','3',...'9'necessarly to move ONLY clock i (where 0 < i <= 8 - there are 9clocks: 0=A, 1=B, ... 8=I) 90 degrees clockwise. So, you have thematrix:
(a[i][0],a[i][1],....,a[i][8],分别是 移动‘1’~移动‘9’中 只把钟 i(此时 0<i <=8 且 0=A钟,1=B钟,...8=I钟)移动90度 ,因此,你可以得到矩阵:)
int a[9][9]= { {3,3,3,3,3,2,3,2,0},
{2,3,2,3,2,3,1,0,1},
{3,3,3,2,3,3,0,2,3},
{2,3,1,3,2,0,2,3,1},
{2,3,2,3,1,3,2,3,2},
{1,3,2,0,2,3,1,3,2},
{3,2,0,3,3,2,3,3,3},
{1,0,1,3,2,3,2,3,2},
{0,2,3,2,3,3,3,3,3} };
That means: to move ONLY the clock 0 (clock A) 90 degrees clockwise,you have to do {3,3,3,3,3,2,3,2,0}, 3 moves of type 1, three moves of type 2, ..., 2 moves of type 8, 0 moves of type 9, etc.
(这意味着:为了只把钟0,即钟A,拨动90度,你只能做一个移动‘1’,然后后面就理解不了了。。- - 没能力的家伙。。)
To move ONLY the clock 8 (clock I), you have to do the moves{0,2,3,2,3,3,3,3,3}: 0 moves of type 1, 2 moves of type 2... 3 movesof type 9....
That's it! You count in a vector v[9] how many moves of each typeyou have to do, and the results will be modulo 4 (%4 - 5 moves ofany type have the same effect 1 move has).The source code:
#include <stdio.h>
int a[9][9]= { {3,3,3,3,3,2,3,2,0},
{2,3,2,3,2,3,1,0,1},
{3,3,3,2,3,3,0,2,3},
{2,3,1,3,2,0,2,3,1},
{2,3,2,3,1,3,2,3,2},
{1,3,2,0,2,3,1,3,2},
{3,2,0,3,3,2,3,3,3},
{1,0,1,3,2,3,2,3,2},
{0,2,3,2,3,3,3,3,3} };
int v[9];
int main() {
int i,j,k;
freopen("clocks.in","r",stdin);
for (i=0; i<9; i++) {
scanf("%d",&k);
for(j=0; j<9; j++)
v[j]=(v[j]+(4-k/3)*a[i][j])%4;
}
fclose(stdin);
k=0;
freopen("clocks.out","w",stdout);
for (i=0; i<9; i++)
for (j=0; j<v[i]; j++)
if (!k) { printf("%d",i+1); k=1; }
else printf(" %d",i+1);
printf("\n");
fclose(stdout);
return 0;
}