usaco 1.4 The Clocks(暴搜)and poj 1166

题意是给你九个只指向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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值