福州省赛 二分
来源:互联网 发布:程序员优秀简历 编辑:程序博客网 时间:2024/06/10 04:02
E - The Longest Straight
题意:给定n个0到m的数字要求找到一个最长的序列(它们的值必须的递增或递减的, 不能存在环),其中0可以代替1到m中的任意一个值,问最长的序列的长度是多少?
题解:本来想的是先把零的个数找到,把不是零的数按照从小到大排列,找到合适的位置把零插进入,找到最长的序列,现在发现同一个数字可能出现多次,排序之后仍然需要处理每个数字出现的次数,因为序列为有序的,所以每个数字只是用一次,又因为下标为1到100000所以可以把下标当做数字来处理,这时把每个数字的出现与否,都记录在数组中,而且用下标表示,其中存储的数字为0或1(0代表没有出现过该数字,1代表出现过该数字),然后从中找到合适的开始数字和结束数字,长度就为序列的长度。每个数字都可以是开始数字所以遍历,从0开始到m,如何找到结束为止,这时候用到了二分来寻找结束数字,其中结束数字和开始数字之间的没有出现的数字的数量不能超过零的个数。
注意:0其实不可以当开始数字,但是用0好处理。下面用代码说明:
代码:
#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<deque>#include<map>#include<cmath>using namespace std;typedef long long ll;const int N= 1e5+7;int visited[N], flag[N];int main() { int n, m, t, num, Max, mid, l, r, zero; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); memset(visited, 0, sizeof(visited)); memset(flag, 0, sizeof(flag)); zero = 0; for(int i = 0; i < n; i++) { scanf("%d", &num); if(num) visited[num] = 1; else zero++; } for(int i = 1; i <= m; i++) { if(visited[i]) flag[i] = flag[i-1]; else flag[i] = flag[i-1] + 1; } Max = -1000000; for(int i = 0; i <= m; i++) { l = i; r = m; while(l <= r) { mid = (l+r)/2; if(flag[mid]-flag[i] > zero) r = mid - 1; else l = mid + 1; } Max = max(Max, r-i); } printf("%d\n", Max); } return 0;}
阅读全文
0 0
- 福州省赛 二分
- 2011福州师范大学晋级赛
- hdu 4068 福州网络赛
- 福州校赛D题
- fzu 1979 福州网络赛I题
- HDU 4066 2011ACM福州网络赛
- 套题总结:2011福州网络赛
- Random Maze(福州网络赛)
- hdu 4070福州网络赛 简单贪心
- 周赛题目 福州 神庙逃亡
- 周赛题目 福州 最长队名
- 周赛题目 福州 数字游戏
- 周赛问题 福州 A - 代码问题
- 周赛问题 福州 B - 单词问题
- 周赛题目 福州 password table
- 周赛问题 福州 B - Somali Pirates
- 周赛问题 福州 龟兔赛跑
- 周赛问题 福州 竞技游戏
- 购物车(angularJS)
- 购物车(ionic)
- 银行账户操作的简单模型
- 关于LD_PRELOAD在Android API HOOK中的应用
- 【Scikit-Learn 中文文档】支持向量机
- 福州省赛 二分
- volatile关键字解析
- shopping
- TCP为什么需要3次握手与4次挥手
- RomanToInt
- XFTP与XSHELL的安装配置
- JavaScript 随机数
- Golang中unsafe.Sizeof()的问题
- make版本降级