poj1029 模拟/枚举
来源:互联网 发布:sql字符串拼接 编辑:程序博客网 时间:2024/04/30 03:54
题意:输入N个硬币,其中有且仅有一枚是假币,通过K次称重,求出哪个是假币,如果无法求出,输出0.
算法1:模拟
首先,对于假币,假设比真币重,那么不管如何组合,有假币的一侧一定重,而如果某枚硬币所在的结果有时重有时轻,则它一定是真币。
例,假设有4枚硬币,其中第2枚为假币,且比真币重,那么:
1 < 2 => 此时结果:硬币1轻,硬币2重,说明二者一定有一枚是假币
1+2 > 3+4 => 此时结果:硬币1所在的集合重,而上一次判断的硬币1为轻,那么硬币1一定是真币。否则,假设硬币1为假币,那么本次的结果应该是1+2 < 3+4
定义:ans[i]=j,初始化为0,若j=INF说明i为真币,否则abs(j)为硬币i偏离真币的指数(即被怀疑为假币的次数),该值越大,越说明是假币
1.对于称重结果为等号的,两边一定是真币,将ans[i]置为INF
2.对于称重结果为小于号的,说明左侧的轻,右侧的重。对于左侧未判断出一定是真币的硬币i,如果ans[i]<=0,那么ans[i]--,如果ans[i]>0,说明i之前被判断过较重,如果i为假币,那么本次的结果一定是左侧的重右侧的轻,与已知结果矛盾,说明硬币i一定是真币,置ans[i]=INF。对于右侧未判断出一定是真币的硬币i,如果ans[i]>=0,那么ans[i]++,否则ans[i]=INF
3.如果称重结果为大于号,说明左侧的重,右侧的轻,处理结果类似步骤3
算法2:枚举,假设第i枚硬币是假币,然后验证K次称重结果,若符合则说明硬币i是假币,若有多个符合,说明无法判断,输出0
#include <iostream>#include <algorithm>#include <string.h>using namespace std;struct COIN{int a[2010];// 当前称的硬币 int k;// 每侧硬币的个数 char result;// 称重的结果 };COIN coins[110];const int INF = 99999;int ans[1010];// 处理当前较轻的硬币 void light(int start, int end, int i){for (int j=start; j<end; j++){if (ans[coins[i].a[j]] != INF){(ans[coins[i].a[j]] <= 0)? ans[coins[i].a[j]]-- : ans[coins[i].a[j]] = INF;}}}// 处理当前较重的硬币 void heavy(int start, int end, int i){for (int j=start; j<end; j++){if (ans[coins[i].a[j]] != INF){(ans[coins[i].a[j]] >= 0)? ans[coins[i].a[j]]++ : ans[coins[i].a[j]] = INF;}}}int main(){int N,K;memset(ans,0,sizeof(ans));// 输入 cin >> N >> K;for (int i=0; i<K; i++){cin >> coins[i].k;for (int j=0; j<2*coins[i].k; j++){cin >> coins[i].a[j];}cin >> coins[i].result;}// 处理 for (int i=0; i<K; i++){if (coins[i].result == '='){for (int j=0; j<2*coins[i].k; j++){ans[coins[i].a[j]] = INF;}}else if (coins[i].result == '<'){light(0,coins[i].k,i);heavy(coins[i].k, 2*coins[i].k, i);}else if (coins[i].result == '>'){heavy(0,coins[i].k,i);light(coins[i].k,2*coins[i].k,i);}}// 输出答案,绝对值最大的为假币,如果个数超过一个,则不能判断哪个是假币,即输出0 int max1,max2,falseCoin;max1 = max2 = -1;for (int i=1; i<=N; i++){if (ans[i] != 99999){if (abs(ans[i]) > max1){max2 = max1;max1 = abs(ans[i]) ;falseCoin = i;}else if (abs(ans[i]) > max2){max2 = abs(ans[i]);}}}(max1==max2)? cout << 0 << endl : cout << falseCoin << endl;}
0 0
- poj1029 模拟/枚举
- poj1029 模拟
- 【模拟】Poj1029 False Coin
- poj1029
- poj1029
- POJ1029
- poj1029
- POJ1029
- POJ1029
- poj1029
- poj1029
- poj1029(找假硬币)模拟
- 2011.12.22 poj1029 暴力枚举【learn from others】
- PHP模拟枚举类型
- 如何模拟枚举类型
- zoj 3627#模拟#枚举
- poj 1944 模拟 枚举
- HDU1238(模拟+枚举)
- 输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数
- Android 之联系人提供程序
- unity Instantiate()克隆预设脚本Start()的执行时机问题
- 002.Pecconfig自定义节点树出现异常数据的提示框-2015年12月29日
- 什么界面架构最好?
- poj1029 模拟/枚举
- 做一个具有阳光思维的人
- 网站开发时间计划表
- rtp over tcp
- HDU 1878:欧拉回路【并查集】
- 64位和32位编译环境下不同数据类型长度的区别
- iOS 8推送注册方式改变的问题
- x264代码剖析(十一):核心算法之宏块分析函数x264_macroblock_analyse()
- 第六届蓝桥杯 软件类省赛真题 第九题:打印大X