CFGym 101194D 题解
一、题目链接
http://codeforces.com/gym/101194/problem/D
二、题意
给定一个数字n和一个数字k,一个n个整数的序列,让你在里面找尽可能多的长度为k的符合“要求”的序列。一个数字不能被重复使用。
要求:对于一个序列A0A1……An, 保证对任意的i(0 <= i < n),都有Ai * 2 <= A(i + 1)。
三、思路
1、我一开始想到的方法是:把n个数排序,从大的数开始使用二分往前找,找到一个就标记一个数,在一次寻找中,如果能找到k个数,那么,结果+1,最后输出结果。这样的时间复杂度为:O(KNlogN),不会超时,但是,这样的想法是错的。比如,这样的样例:n = 6, k = 3, 440 220 110 105 40 2。同样地,从小往大找也是不行的,样例性质相同:n = 6, k = 3, 2 40 110 115 220 440。也就是说,从大往小找,对于第i个被找到的元素e,不应该找第一个小于等于e / 2的元素。所以,这种想法是直接跪在这个样例上了。注意,C++是没有内置的在有序表查找第一个小于等于给定值的函数,那么,我们可以把整个序列取为相反数(全部变成负),按升序排序,原本要查找小于等于就变成要查找大于等于了,就可以使用内置的lower_bound了。另外,要注意一点,现在二分的查找值是当前元素值a[i] / 2,因为原本数值越大的,取负后越小,越除则越大,最后相当于还是在求从大往小的。另外的话,负数除法,不要用右移运算符。
2、第二种方法:对原数组直接排序(不用取相反数),二分最后的结果,然后对二分得到的中间值mid,使用排序后的数字序列的前mid个数当作mid个子序列的领头,表明我想测试下是否存在mid这么多个序列。然后,枚举每一个领头,都使用lower_bound去后面查找k - 1个符合“要求”的数。如果这mid个领头都能找到k个数来满足“要求”,那么,说明这个mid是可以的,否则说明不行。但是,这个看起来没错的想法,又会跪在这个样例上:n = 8, k = 4, 1 2 3 4 110 220 225 440。仔细想想,这其实只是把前一个想法往后移了,枚举每一个领头后,查找后面k-1个数的过程和前一个方法一样的。
3、第三种方法:这个问题,实际上就相当于给mid列每列k个座位安排学生就坐,前面第二种方法,就是一列一列地排。而这种方法,就是一行一行地排,如果能排满所有座位,说明这个mid是可以的。另外的话,为什么是选前mid个当领头呢,这就贪心的思想了,如果选后面的数当领头,那选这前mid里面的数更好,因为他们更小。
四、源代码
1、方法一(WA on test 2):
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; LL a[MAXN]; bool vis[MAXN]; int t, n, k; vector<int> tmp; int main() { #ifndef ONLINE_JUDGE freopen("Dinput.txt", "r", stdin); #endif // ONLINE_JUDGE ; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); ; i <= n; ++i) { scanf("%lld", a + i); a[i] = -a[i]; } memset(vis, , sizeof(vis)); ; sort(a + , a + n + ); ; i <= n; ++i) { if(vis[i])continue; ; int idx = i; ; j <= k - ; ++j) { idx = lower_bound(a + , a + n + , a[idx] / ) - a; while(idx <= n && vis[idx])idx++; if(idx <= n) { cnt++; vis[idx] = true; } if(idx > n)break; } if(cnt >= k)ans++; } printf("Case #%d: %d\n", tc++, ans); } ; }
2、方法二(WA on test 2):
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; LL a[MAXN]; bool vis[MAXN]; int t, n, k; bool test(int ans) { ; memset(vis, , sizeof(vis)); ; i <= ans; ++i) { if(vis[i])continue; ; int idx = i; ; j <= k - ; ++j) { idx = lower_bound(a + ans + , a + n + , a[idx] * ) - a; while(idx <= n && vis[idx])idx++; if(idx <= n) { cnt++; vis[idx] = true; } if(idx > n)break; } if(cnt >= k)tmp++; } if(tmp < ans)return false; else if(tmp >= ans)return true; } int main() { #ifndef ONLINE_JUDGE //freopen("Dinput.txt", "r", stdin); #endif // ONLINE_JUDGE ; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); ; i <= n; ++i) { scanf("%lld", a + i); } sort(a + , a + n + ); , high = n + , mid; ) { mid = (high + low) / ; if(test(mid)) low = mid; else high = mid; } printf("Case #%d: %d\n", tc++, low); } ; }
3、方法三(Accepted):
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; LL a[MAXN]; bool vis[MAXN]; int t, n, k; vector<LL> vecs[MAXN]; bool test(int mid) { ; i <= n; ++i)vecs[i].clear(); ; i <= mid; ++i)vecs[i].push_back(a[i]); , sz = ; ; i <= n; ++i) { sz = vecs[j].size(); * vecs[j][sz - ]) { vecs[j].push_back(a[i]); j++; ; } } ; i <= mid; ++i)if(vecs[i].size() < k)return false; return true; } int main() { #ifndef ONLINE_JUDGE freopen("Dinput.txt", "r", stdin); #endif // ONLINE_JUDGE ; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); ; i <= n; ++i)scanf("%lld", a + i); sort(a + , a + n + ); , high = n + , mid; ) { mid = (high + low) / ; if(test(mid)) low = mid; else high = mid; } printf("Case #%d: %d\n", tc++, low); } ; }
4、方法三——优化版:
#include<bits/stdc++.h> using namespace std; typedef long long LL; ; LL a[MAXN], b[MAXN]; int t, n, k; bool test(int mid) { ;i < mid;++i)b[i] = a[i]; , j = ; for(int i = mid; i < n; ++i) { ) { b[j++] = a[i]; if(j >= mid) { ++tmp; j = ; } } } return tmp >= k; } int main() { #ifndef ONLINE_JUDGE freopen("Dinput.txt", "r", stdin); #endif // ONLINE_JUDGE ; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); ; i < n; ++i)scanf("%lld", a + i); sort(a, a + n); , high = n + , mid; ) { mid = (high + low) / ; if(test(mid)) low = mid; else high = mid; } printf("Case #%d: %d\n", tc++, low); } ; }
CFGym 101194D 题解的更多相关文章
- CFGym 101490J 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你n个点,代表学生所在位置,n个点,代表老师所在位置.每个学生分配一个老师.让你找出一个最小的学生 ...
- CFGym 101490E 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你一个图,n个点,m条边,一个x,从顶点1走到顶点n.假设从顶点1走到顶点n的最短路为d,x代表你 ...
- CFGym 101161I 题解
一.题目链接 http://codeforces.com/gym/101161/problem/I 二.题意 给定一棵树,一个初始的省会城市,若干个询问,0表示修改省会城市,1表示查询去省会必须经过指 ...
- CFGym 100198G 题解
一.题目链接 http://codeforces.com/gym/100198/problem/G 二.题意 看样例就能明白,写表达式解析器. 三 .思路 一看这题目,立马就会想到“后缀表达式”,考虑 ...
- CFGym 101194L 题解
一.题目链接 http://codeforces.com/gym/101194/problem/L 二.题意 有4个队伍,要打6场比赛(刚好每两个队伍都能相互比一次),若A和B比赛有3种结果: A赢B ...
- CFGym 101505I 题解
一.题目链接 http://codeforces.com/gym/101505 二.题意 这题其实主要就是题意,理解题意后,就是水题了.我想了下,主要原因就是这几点: 1.题意太过英文化,很多句子不能 ...
- CFGym 100211J 题解
一.题目 二.题意 给定一个字母表(最多也就是英文小写字母的前10个字母),一个交换表,两个字符串,判断字符串A能否通过交换表的交换方式变成字符串B. 三.思路 1.一开始,比赛时,我半模拟半记忆化地 ...
- [CF-GYM]Abu Tahun Mod problem题解
前言 这道题比较简单,但我还是想了好一会 题意简述 Abu Tahun很喜欢回文. 一个数组若是回文的,那么它从前往后读和从后往前读都是一样的,比如数组\(\left\{1\right\},\left ...
- Gym 101194D / UVALive 7900 - Ice Cream Tower - [二分+贪心][2016 EC-Final Problem D]
题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...
随机推荐
- POJ 2391 Ombrophobic Bovines(二分+拆点+最大流)
http://poj.org/problem?id=2391 题意: 给定一个无向图,点i处有Ai头牛,点i处的牛棚能容纳Bi头牛,求一个最短时间T,使得在T时间内所有的牛都能进到某一牛棚里去. 思路 ...
- activemq、rabbitmq、kafka原理和比较
一.activemq 虽然是java写的消息队列,但是提供Java, C, C++, C#, Ruby, Perl, Python, PHP各种客户端,所以语言上是没什么问题的.配置和使用,基本上是j ...
- Spring 及 SpringMVC的web.xml配置详解
出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...
- Android-----购物车(包含侧滑删除,商品筛选,商品增加和减少,价格计算,店铺分类等)
电商项目中常常有购物车这个功能,做个很多项目了,都有不同的界面,选了一个来讲一下. 主要包含了 店铺分类,侧滑删除,商品筛选,增加和减少,价格计算等功能. 看看效果图: 重要代码: private v ...
- 机器学习算法--svm实战
1.不平衡数据分类问题 对于非平衡级分类超平面,使用不平衡SVC找出最优分类超平面,基本的思想是,我们先找到一个普通的分类超平面,自动进行校正,求出最优的分类超平面 测试代码如下: import nu ...
- HDU 1495 非常可乐 bfs 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=1495 第三个杯子的盛水量可由前两个杯子得到,而前两个杯子状态总数在100*100以内,穷举可实现 #includ ...
- 函数响应式编程RxJava
RxJava 到底是什么 一个词:异步. RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event- ...
- 【LeetCode 222_完全二叉树_遍历】Count Complete Tree Nodes
解法一:递归 int countNodes(TreeNode* root) { if (root == NULL) ; TreeNode *pLeft = root->left; TreeNod ...
- 201621123006 《Java程序设计》第8周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 源代码如下: 由源代码可 ...
- (转)OAuth 2.0的设计思路
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为R ...