POJ1166 the clocks

题目大意:给出原始9个表watch,通过9个操作operation,求最少操作数使得9个watch都指向12点.每一次operation,会对相应涉及到的watch顺时针调整15分钟.

 

思路:

对于每种操作,操作次数不会超过3次,因为4次以上就会有无意义的步数,为什么无意义?因为和前面的操作状态重复了.

为什么这样会重复呢?其他的操作对表的影响下再操作就不会与重复了呀!这是因为每一次操作都是独立的,谁在前谁在后没有关系,同样的2次操作A+B,A先开始和B先开始的结果一样,所以别的操作在都可以忽略,在这样的情况下,对一个表转动2次和转动6次是一样的   

状态数有:4^9,枚举每一种操作,那么肯定会有结果,如果挑选结果?每一种操作都会影响到相应的watches,那么在枚举的过程中判断每一个watch是否都是处于指向12点的状态,是则可以跳出.

这样就跳出是最短的步数么?是因为for循环在枚举的时候就是从最小的操作数开始枚举.这样跳出怎么输出结果:直接for循环依次输出1到9的操作的次数的结果即可.

为什么是依次?一定是依次的么?其实最短序列可以找到,但是这个序列的顺序怎安排对最后的结果都没有影响,因为每一次的操作都是独立的,对每一个操作不会依赖于其他操作.

operation[i]表示第i次操作

watch[i]表示第几个表的状态

tmp[i]表示的是第几个表在相应操作后的临时状态

 

AC Program:

 

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm> 
#include<string.h>
#include<map>
using namespace std;
int operation[10];
int  watch[10];
int tmp[10]; 
int main()
{
for(int i=1;i<=9;i++)
     cin>> watch[i]; 
for( operation[1]=0;operation[1]<4;operation[1]++)
for( operation[2]=0;operation[2]<4;operation[2]++)
for( operation[3]=0;operation[3]<4;operation[3]++)
for( operation[4]=0;operation[4]<4;operation[4]++)
for( operation[5]=0;operation[5]<4;operation[5]++)
for( operation[6]=0;operation[6]<4;operation[6]++)
for( operation[7]=0;operation[7]<4;operation[7]++)
for( operation[8]=0;operation[8]<4;operation[8]++)
for( operation[9]=0;operation[9]<4;operation[9]++)
{
     tmp[1]=(  watch[1]+operation[1]+operation[2]+operation[4])%4; 
     tmp[2]=(  watch[2]+operation[1]+operation[2]+operation[3]+operation[5])%4;
     tmp[3]=(  watch[3]+operation[2]+operation[3]+operation[6])%4;
     tmp[4]=(  watch[4]+operation[1]+operation[4]+operation[5]+operation[7])%4;
     tmp[5]=(  watch[5]+operation[1]+operation[3]+operation[5]+operation[7]+operation[9])%4;
     tmp[6]=(  watch[6]+operation[3]+operation[5]+operation[6]+operation[9])%4;
     tmp[7]=(  watch[7]+operation[4]+operation[7]+operation[8])%4;
     tmp[8]=(  watch[8]+operation[5]+operation[7]+operation[8]+operation[9])%4;
     tmp[9]=(  watch[9]+operation[6]+operation[8]+operation[9])%4;
     if(tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7]+tmp[8]+tmp[9]==0)
     {
        for(int i=0;i<operation[1];i++) cout<<"1 ";
        for(int i=0;i<operation[2];i++) cout<<"2 ";
        for(int i=0;i<operation[3];i++) cout<<"3 ";
        for(int i=0;i<operation[4];i++) cout<<"4 ";
        for(int i=0;i<operation[5];i++) cout<<"5 ";
        for(int i=0;i<operation[6];i++) cout<<"6 ";
        for(int i=0;i<operation[7];i++) cout<<"7 ";
        for(int i=0;i<operation[8];i++) cout<<"8 ";
        for(int i=0;i<operation[9];i++) cout<<"9 ";
        cout<<endl;
        //system("pause");
        return 0;                                                                                                                                                                                      
     } 
} 

} 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值