NYOJ 133 子序列 (离散化)
描述
给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次。
如2 8 8 8 1 1,所求子串就是2 8 8 8 1。
- 输入
第一行输入一个整数T(0<T<=5)表示测试数据的组数每组测试数据的第一行是一个整数N(1<=N<=1000000),表示给定序列的长度。随后的一行有N个正整数,表示给定的序列中的所有元素。数据保证输入的整数都不会超出32位整数的范围。 - 输出
对于每组输入,输出包含该序列中所有元素的最短子序列的长度 - 样例输入
2
5
1 8 8 8 1
6
2 8 8 8 1 1 - 样例输出
2
5
分析:
由于给出的数据的变化范围比较大,可能整个序列中的数为1 10000 10000 10000 1 10000这样的话我们在遍历寻找的时候肯可能出现数字比较大,没有办法进行标记。所以我们采用离散化的思想,上面的序列去重后排序,然后用他们在排序好的序列中的位置lai表示这个数,这样的话序列就变为0 1 1 1 0 1 数值的不会太大完全可以标记。
然后就是用尺取法取得所要的序列的长度,长度最短的就是要包含了所有的数字,定义一个当前序列开始的起始下标,如果到现在这个数一共有op(op为不同数字的个数)个不同的数字,那么这就是一个满足要求的序列,保存所有满足序列的长度最小值,而且在这个序列的基础上我们可以通过将序列最前面的重复数字去掉来减少数列长度。
就这样循环找,当找到op个不同数字的时候,就将起始下标往后移动,直到不同数字的个数部位op时,在往后找。
代码:
#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
int num[1000009];///num数组保存的是原始的序列
int a[1000009];///a数组保存的是去掉重复值之后的序列
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&num[i]);
a[i]=num[i];
}
sort(a,a+n);
int op=1;
for(int i=1; i<n; i++)
{
if(a[i]!=a[i-1])
a[op++]=a[i];///op中保存的就是去掉重复值之后的序列
}
// cout<<op<<endl;
int left;
int right;
for(int i=0; i<n; i++)///离散化,原来的数值可能比较分散,利用离散化的思想吧这些数据都缩小
{
left=0;
right=op-1;
while(left<=right)
{
int mid=(left+right)/2;
if(a[mid]==num[i])
{
num[i]=mid;
break;
}
else if(a[mid]<num[i])
left=mid+1;
else
right=mid-1;
}
// printf("%d ",num[i]);
}
int sum=0;
int bj[1000009]= {0};
int le=0;
int ans=9999999;
for(int i=0; i<n; i++)///尺取法
{
if(bj[num[i]]==0) sum++;///sum表示的是当前的序列中有几个不同的数
bj[num[i]]++;
while(sum==op)///当刚好有op个不同数的时候
{
ans=min(ans,i-le+1);///当前序列中的数与之前保存的数的个数
bj[num[le]]--;///吧最前面的那个数标记释放
if(bj[num[le]]==0)
sum--;
le++;
}
}
printf("%d\n",ans);
}
return 0;
}
NYOJ 133 子序列 (离散化)的更多相关文章
- UOJ Round #15 [构造 | 计数 | 异或哈希 kmp]
UOJ Round #15 大部分题目没有AC,我只是水一下部分分的题解... 225[UR #15]奥林匹克五子棋 题意:在n*m的棋盘上构造k子棋的平局 题解: 玩一下发现k=1, k=2无解,然 ...
- 子序列 NYOJ (尺取法+队列+hash) (尺取法+离散化)
子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...
- nyoj133_子序列_离散化_尺取法
子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...
- 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹
一, 最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1< ...
- Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树
D. Zip-line 题目连接: http://www.codeforces.com/contest/650/problem/D Description Vasya has decided to b ...
- 洛谷-P1439 【模板】最长公共子序列 (DP,离散化)
题意:给两个长度为\(n\)的全排列,求他们的LCS 题解:这题给的数据范围到\(10^5\),用\(O(n^2)\)的LCS模板过不了,但由于给的是两个全排列,他们所含的元素都是一样的,所以,我们以 ...
- NYOJ-214 单调递增子序列(二) AC 分类: NYOJ 2014-01-31 08:06 233人阅读 评论(0) 收藏
#include<stdio.h> #include<string.h> int len, n, i, j; int d[100005], a[100005]; int bin ...
- nyoj 36 最长公共子序列【LCS模板】
最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...
- NYOJ 214 最长上升子序列nlogn
普通的思路是O(n2)的复杂度,这个题的数据量太大,超时,这时候就得用nlogn的复杂度的算法来做,这个算法的主要思想是只保存有效的序列,即最大递增子序列,然后最后得到数组的长度就是最大子序列.比如序 ...
随机推荐
- PHP SQL查询结果在页面上是乱码
今天系统网页出现这样一个问题:下图左边类型栏数据是没显示出来 打印SQL查询的数据是有的 原因是:————> eval函数里'return '这一字符串一定要有空格哈,没有空格,这语句就是错的. ...
- 【Linux】- 简明Vim练习攻略
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...
- laravel获取当前认证用户登录
可以通过Auth门面访问认证用户: 要在方法上面声明 use Auth: 获取当前认证用户使用 $user = Auth::user(); 获取用户认证ID $id = Auth::id;
- 微信小程序 对接口常用
@import '../expert/expert.wxss'; FZ._get('https://didu2.didu86.com/issun/index.php/Home/goodstype/ ...
- linux 内核态调试函数BUG_ON()[转]
一些内核调用可以用来方便标记bug,提供断言并输出信息.最常用的两个是BUG()和BUG_ON(). 当被调用的时候,它们会引发oops,导致栈的回溯和错误信息的打印.为什么这些声明会导致 oops跟 ...
- EL语法 ${person.id} 这里面的id指的是实例对象的成员变量
EL语法 ${person.id} 这里面的id指的是实例对象的成员变量
- 基本数据类型用 == 判断的是值 ,对象用 == 判断的是地址 , 判断值的话用 equals()
基本数据类型用 == 判断的是值 ,对象用 == 判断的是地址 , 判断值的话用 equals() 字符串是String的实例
- 【bzoj2560】串珠子 状压dp+容斥原理
题目描述 有 $n$ 个点,点 $i$ 和点 $j$ 之间可以连 $0\sim c_{i,j}$ 条无向边.求连成一张无向连通图的方案数模 $10^9+7$ .两个方案不同,当且仅当:存在点对 $(i ...
- Codeforces Round #525 Div. 2 自闭记
A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...
- Doves and bombs UVA - 10765(统计割顶所连接的连通块的数量)
题意:给定一个n个点的连通的无向图,一个点的“鸽子值”定义为将它从图中删去后连通块的个数. 求对应的点 和 每个点的“鸽子值” 用一个数组在判断割顶的那个地方 累加标记一下所连接的连通块的数量即可 初 ...