抽签问题
来源:互联网 发布:软件测试课程 编辑:程序博客网 时间:2024/04/28 11:56
一.题意
你的朋友提议玩一个游戏:将写有数字的n个纸片放入口袋中,你可以从口袋中抽取4次纸片,每次记下纸片上的数字后都将其放回口袋中。如果这4个数字的和是m,就是你赢,否则就是你的朋友赢。你挑战了好几回,结果一次也没赢过,于是怒而撕破口袋,取出所有纸片,检查自己是否真的有赢的可能性。请你编写一个程序,判断当纸片上所写的数字是k1, k2, …, kn时,是否存在抽取4次和为m的方案。如果存在,输出Yes;否则,输出No。(1<=n<=1000,1<=m<=1e8,1<=k<=1e8)
二.解法
2.1 暴力解法
// 通过四重循环枚举所有方案 for (int a = 0; a < n; a++) { for (int b = 0; b < n; b++) { for (int c = 0; c < n; c++) { for (int d = 0; d < n; d++) { if (k[a] + k[b] + k[c] + k[d] == m) { f = true; } } } } }
2.2 解法
最内层循环即检查是否存在d,使得k[a]+k[b]+k[c]+k[d]==m,将d移到左边
K[d]==m-k[a]-k[b]-k[c],可以对k数组进行排序,查找速度为logn
bool BinarySearch(int x){ int L=0,R=N; //x的存在范围是k[L],k[L+1],...k[R-1] while(R-L>=1){ int mid=(L+R)/2; if(K[mid]==x) return true; else if (K[mid]<x) L=mid+1; else R=mid; } return false;}void solve(){ sort(K,K+N); bool f=false; for(int a=0;a<N;++a) for(int b=0;b<N;++b) for(int c=0;c<N;++c) if(BinarySearch(m-k[a]-k[b]-k[c])) f=true; if(f) puts("YES"); else puts("NO");}
2.3 解法
着眼于内侧的两个循环,检查最内层循环即检查是否存在c,d,使得K[c]+K[d]==m-k[a]-k[b],预先枚举出k[c]+k[d]所得的n^2个数,并排好序,就可以使用二分.
循环时间和排序时间都是
void solve(){ for(int c=0;c<N;++c) for(int d=0;d<N:++d) KK[c*N+d]=K[c]+K[d]; sort(KK,KK+N*N);}
- 抽签问题
- 抽签问题
- 抽签问题
- 抽签问题
- 抽签问题
- 程序设计--抽签问题
- 抽签问题改进算法
- 抽签问题优化
- 复杂的抽签问题
- 抽签
- 抽签
- 抽签
- 抽签
- 抽签
- 抽签
- 抽签
- 抽签
- 抽签
- vs2012配置opencv2.4.6
- 工作队列(workqueue)
- Eclipse + CDT + MinGW 编程环境配置
- Hibernate用法:查询,更新,删除!
- new和malloc的区别
- 抽签问题
- 计算 任意大N的M次方
- linux中shell变量$#,$@,$0,$1,$2的含义解释
- Quartz教程(一)- HelloWorld
- C# 大量函数
- 无名管道
- 消息队列(System V)
- [收藏转载]C# GDI+ 简单绘图
- jquery中获取键盘按键