poj_1166_枚举(或者递归/回溯)

题目描述:

    给出九个闹钟。闹钟指向0-3-6-9四个点钟方向。有九个设定好的动作,分别指定对某几个闹钟正向拨动3点钟方向。输入给出九个闹钟初始指向,求用设定好的动作,最少用几组就能够把所有闹钟都拨到0点钟方向。

 

解题思路:

   一开始想用回溯做。结果卡在用一个循环+回溯会导致重复计算之前做过的动作上。用枚举做,算了算只要最终结果move个数超过5,效率就比回溯高好多了。所以就用枚举,把指令简化成+1动作,点钟化为0-1-2-3。

    第一次交pe了。注意输出………………回车的问题。

 

代码:

#include <stdio.h>
#include <stdio.h>
#define MAX 100000

int r[10][10] = {{0,0,0,0,0,0,0,0,0,0},
                 {0,1,1,0,1,1,0,0,0,0},{0,1,1,1,0,0,0,0,0,0},{0,0,1,1,0,1,1,0,0,0},
                 {0,1,0,0,1,0,0,1,0,0},{0,0,1,0,1,1,1,0,1,0},{0,0,0,1,0,0,1,0,0,1},
                 {0,0,0,0,1,1,0,1,1,0},{0,0,0,0,0,0,0,1,1,1},{0,0,0,0,0,1,1,0,1,1}};
int matrix[10], ind[10];

main()
{
   int i,i1,i2,i3,i4,i5,i6,i7,i8,i9;
   int num,min=MAX,f;
  
   for(i=1;i<=9;i++)
      scanf("%d",&matrix[i]);
   //枚举所有可能
   for(i1=0;i1<=3 ;i1++)
      for(i2=0;i2<=3;i2++)
         for(i3=0;i3<=3;i3++)
            for(i4=0;i4<=3;i4++)
               for(i5=0;i5<=3;i5++)
                  for(i6=0;i6<=3;i6++)
                     for(i7=0;i7<=3;i7++)
                        for(i8=0;i8<=3;i8++)
                           for(i9=0;i9<=3;i9++)
                           {
                              f=1;
                              i=1;
                              num = i1+i2+i3+i4+i5+i6+i7+i8+i9;
                              if(num>=min)
                                 break;
                              while(i<=9)
                                                         
                                 if(0 !=(matrix[i]+i1*r[1][i] + i2*r[2][i] + i3*r[3][i] + i4*r[4][i] + i5*r[5][i]+ i6*r[6][i]+ i7*r[7][i]+ i8*r[8][i]+ i9*r[9][i])%4 )
                                 {
                                    f=0;
                                    break;
                                                         
                                 i++;
                              }
                              if(1==f)
                              {
                                    min = num;
                                    ind[1] = i1;
                                    ind[2] = i2;
                                    ind[3] = i3;
                                    ind[4] = i4;
                                    ind[5] = i5;
                                    ind[6] = i6;
                                    ind[7] = i7;
                                    ind[8] = i8;
                                    ind[9] = i9;
                              }
                           }
   // 输出ind
   for(i=1;i<=9;i++)
      if(ind[i]!=0)
         num = i;
   for(i=1;i<num;i++)
   {
       while(ind[i]>0)
       {
          printf("%d ",i);
          ind[i]--;
       }
   }
   while(ind[num]>1)
   {
      printf("%d ",num);
      ind[num]--;
   }
   printf("%d\n",num);
  
   system("pause");
   return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值