poj1029 False coin
来源:互联网 发布:后期软件培训 编辑:程序博客网 时间:2024/06/06 00:33
链接:http://poj.org/problem?id=1029
有个类似的题是在之前学枚举的时候遇到过,之前的那个例子要简单些。但原理是一样的。所以拿来这个题借鉴一下。
对于假币,存在两种情况:比真币重,或者,比真币轻。又总共有n个硬币,所以有2*n那种情况。
对于每一个硬币,要满足题中m个比对结果,则这个硬币为假硬币。
咳咳。。。当然对于一般的数据,上面的方法是正确的。但对于某些特殊的数据还是要进行判断。
这里,我给两组数据:
5 2
1 1 4
=
1 2 5
=
answer:3
6 2
1 1 4
=
1 2 5
=
answer:0
在第一个例子中,我们可以发现,硬币3是满足所有的比对结果的,所以3是假硬币。
而对于第二个例子,我们又可以发现,硬币3和6均满足所有的比对结果。而这时,结果就有可能不对,所以我在这里设置了temp变量,来排除这种情况。
还有一个例子:
2 1
1 1 2
>
answer:0
这个代码刚写好的时候有很多bug,所以修修补补之后,在最后的判断条件上有点乱。主要就是用flag变量来记录不同的情况来进行判断。
#include<stdio.h>#include<string.h>int left[105][505],right[105][505];//left[i][j]用于存储左边天平的硬币//right[i][j]用于存储右边天平的硬币char res[105][1];//res[i][j]用来存储每次比对的结果,即“>”、“<”、“=”int n,k,p;int find(int *seq,int x)//查找x是否存在数列seq中{ int i; for(i=0;i<505;i++) if(seq[i]==x) return 1;return 0;}int IsLight(int x)//如果假币比真币轻{int i;for(i=0;i<k;i++)switch(res[i][0]){ case '<':if(!find(right[i],x))//对于“>”,则假币必定存在于右盘 return 0; break; case '>':if(!find(left[i],x))//对于“<”,则假币必定存在于左盘 return 0; break; case '=':if(find(left[i],x)||find(right[i],x))//对于“=”,则假币不存在任何一个盘 return 0; break;}return 1;}int IsHeavy(int x)//如果假币比真币重,同上{int i;for(i=0;i<k;i++)switch(res[i][0]){ case '<':if(!find(left[i],x)) return 0; break; case '>':if(!find(right[i],x)) return 0; break; case '=':if(find(left[i],x)||find(right[i],x)) return 0; break;}return 1;}int main(){int i,j;int pos1,pos2,flag1,flag2,ans,temp;while(scanf("%d%d",&n,&k)!=EOF){flag1=0;flag2=0;ans=0;pos1=0;pos2=0;temp=0;memset(left,0,sizeof(left));memset(right,0,sizeof(right)); for(i=0;i<k;i++) { scanf("%d",&p); for(j=0;j<p;j++) scanf("%d",&left[i][j]); for(j=0;j<p;j++) scanf("%d",&right[i][j]); getchar(); scanf("%c",&res[i][0]); } for(i=1;i<=n;i++)//枚举每一个硬币 //此题中假币只有一个,所以结果唯一 { if(IsLight(i)){ pos1=i;flag1++;}if(IsHeavy(i)){pos2=i;flag2++;} if((flag1==flag2)&&flag1&&flag2&&pos1==pos2&&pos1!=temp) {ans++;temp=pos1; } }if((flag1==1)&&!flag2)//一般的数据,只有一个比真币轻的假硬币,满足所有比对结果 printf("%d\n",pos1);if(!flag1&&(flag2==1))//一般的数据,只有一个比真币重的假硬币,满足所有比对结果 printf("%d\n",pos2);if((flag1==flag2)&&flag1&&flag2)//比对的所有结果是“等号”{if(pos1==pos2&&ans==1)//同一个硬币,且只有一个,即ans==1(针对以上两个例子) printf("%d\n",pos1);elseprintf("%d\n",0);//否则为0,如第二个例子和第三个例子} if((!flag1&&!flag2)||((flag1>1||flag2>1)&&(flag1!=flag2)))//flag1=0&&flag2=0,没有一个满足所有比对结果的硬币//flag1>1||flag2>1且flag1!=flag2,有多个满足所有结果的硬币,即结果不唯一,不满足题意printf("%d\n",0);} return 0;}
0 0
- 【模拟】Poj1029 False Coin
- poj1029 False coin
- ***POJ1029 False coin ACM解题报告(贪心难题)
- False coin
- False coin
- False coin
- poj1029
- poj1029
- POJ1029
- poj1029
- POJ1029
- POJ1029
- poj1029
- poj1029
- 1029 False coin
- 1029 False coin
- poj 1029 False Coin
- 1029 False coin
- ajaxfileupload修复版
- cocos2d-x学习笔记(持续更新)
- Android与java的关系
- 跟我一起写makefile
- PL/SQL_触发器5(建立系统事件触发器)
- poj1029 False coin
- C++开平方与乘方
- Gallery实现图片的画廊展示
- 正则表达式
- Android中用ViewPager和Fragment内嵌WebView
- Linux 2.6 Alarm信号中断遇上函数阻塞
- Box2D基本元素简介 Box2D源码示例简介
- Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
- 第五周项目1-三角形类的构造函数(4)