您的位置:首页 > 其它

智力游戏

2015-10-11 18:35 309 查看

智力游戏


【Description】
whitecloth 最近迷上了一个你小时候已经玩厌了的游戏:移火柴棒。
他现在吵着要你陪他玩,你没有办法,只好写一个程序来完成这个工
作了。
你被给出了一个火柴拼成的等式,比如说下面这个:( 5 + 7 = 7 )
它显然是不成立的,但是我们可以通过移动一个其中的火柴使得它成
立。变成如下的一个等式:( 6 + 1 = 7 )
现在给出一个类似的等式,请问最少移动多少根火柴可以使得它变成
一个成立的等式。
【Input】
三个整数,表示原等式中的两个加数以及和
【Output】
一个数,表示最小移动几根火柴能使等式成立,不允许改变位数以及
符号,不要制造0 开头的数。
【Sample Input】
5 7 7
【Sample Output】
1
【Hint】
对于100%的数据,每个数在0 到999 之间

先写出一个8,把上面的7根火柴编号,则0-9都可以用着7根火柴中的某些来拼成,那么用到了状态压缩,sta[i]用一个二进制串表示由那几根火柴拼成,所以枚举两个改变后的加数,则其和也可知道,那么原来数字能拼成新数字的前提是总共的火柴数量相同,在最优的情况下不考虑一个数的总位数改变的情况,(考虑一定对,不考虑是贪心的剪枝,正确性显然),考虑一下,如果新变成的数字的某个位置上的火柴原来数字上有就不用动,如果原来数字上某个位置的火柴新数字中没有就把它拿出来,最后拿里少补在哪里,因为总的个数相同,所以一定能补出来,综上所述,只考虑需要拿走多少个,找最小值就好。题解上说注意1有两种,一种左对齐,一种右对齐,但是我没考虑也过了,应该因为数据中没有这种情况吧。

[code] 1 #include<cstdio>
2 using namespace std;
3 int A,B,C;
4 int sta[1002];
5 int w[1002]={6,2,5,5,4,5,6,3,7,6};
6 int p[1002];
7 void Pre(){
8     sta[0]=(1<<0)+(1<<1)+(1<<2)+(1<<3)+(1<<4)+(1<<5);
9     sta[1]=(1<<4)+(1<<5);
10     sta[2]=(1<<0)+(1<<5)+(1<<6)+(1<<2)+(1<<3);
11     sta[3]=(1<<0)+(1<<5)+(1<<6)+(1<<4)+(1<<3);
12     sta[4]=(1<<1)+(1<<6)+(1<<5)+(1<<4);
13     sta[5]=(1<<0)+(1<<1)+(1<<6)+(1<<4)+(1<<3);
14     sta[6]=(1<<0)+(1<<1)+(1<<2)+(1<<3)+(1<<4)+(1<<6);
15     sta[7]=(1<<0)+(1<<4)+(1<<5);
16     sta[8]=(1<<0)+(1<<1)+(1<<2)+(1<<3)+(1<<4)+(1<<5)+(1<<6);
17     sta[9]=(1<<0)+(1<<1)+(1<<3)+(1<<4)+(1<<5)+(1<<6);
18 }
19 int TJ(int y,int x){
20     int cnt=0;
21     y=sta[y];
22     x=sta[x];
23     for(int i=0;i<27;i++){
24         if(((1<<i)&x)&&!((1<<i)&y)) cnt++;
25     }
26     return cnt;
27 }
28 int ans=0;
29 int main(){
30     Pre();
31     scanf("%d%d%d",&A,&B,&C);
32     p[0]=1;
33     for(int i=0;i<=1000;i++){
34         int o=i;
35         while(o!=0){
36             p[i]++;
37             o/=10;
38         }
39     }
40     for(int i=10;i<=999;i++){
41         w[i]=w[i/10]+w[i%10];
42         sta[i]=(sta[i/10]<<7)+sta[i%10];
43     }
44     //printf("%d         %d\n",sta[1],sta[5]);
45     ans=w[A]+w[B]+w[C];
46     for(int i=0;i<=999;i++){
47         for(int j=0;j<=999;j++){
48             if(p[i]==p[A]&&p[j]==p[B]&&p[i+j]==p[C]){
49                 if(w[i]+w[j]+w[i+j]==w[A]+w[B]+w[C]){
50                     int ls=TJ(i,A)+TJ(j,B)+TJ((i+j),C);
51                     if(ls<ans) ans=ls;
52                 }
53             }
54         }
55     }
56 //    printf("%d         %d\n",sta[1],sta[5]);
57 //    printf("%d",TJ(1,5));
58     printf("%d",ans);
59     getchar(); getchar(); getchar();
60 }

View Code

 

posted @ 2015-10-11 18:35 Lenicodes 阅读(...) 评论(...) 编辑 收藏

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: