子序列 NYOJ (尺取法+队列+hash) (尺取法+离散化)
子序列
- 描述
-
给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少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 - 来源
- POJ月赛改编
-
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 1000044
#define INF 1000000009
#define eps 0.00000001
/*
利用队列从前到后遍历数组元素
当前元素未在之前出现过,更新ans为队列元素个数
当前元素在之前出现过
如果当前队首元素在hash表中出现次数多于1次,pop
*/
int T, n, aim, a[MAXN],b[MAXN];
typedef struct Hashnode
{
int data;
int cnt;
struct Hashnode* next;
}*List;
typedef struct Hashtb
{
List* L;
}*HashTable;
HashTable Init()
{
HashTable H = (HashTable)malloc(sizeof(Hashtb));
H->L = (List*)malloc(sizeof(List)*MAXN);
for (int i = ; i < MAXN; i++)
{
H->L[i] = (List)malloc(sizeof(Hashnode));
H->L[i]->data = ;
H->L[i]->cnt = ;
H->L[i]->next = NULL;
}
return H;
}
int Hash(int x)
{
return x%MAXN;
}
void clear(HashTable H)
{
for (int i = ; i < MAXN; i++)
{
H->L[i]->data = ;
H->L[i]->cnt = ;
H->L[i]->next = NULL;
}
}
List find(int x, HashTable H)
{
List l = H->L[Hash(x)];
List p = l->next;
while (p != NULL&&p->data != x)
p = p->next;
return p;
}
int cnt(int x, HashTable H)
{
List p = find(x, H);
if (p == NULL)
return -;
else
{
if (p->cnt > )
{
p->cnt--;
return p->cnt + ;
}
else
return p->cnt;
}
}
bool Insert(int x, HashTable H)
{
List l = H->L[Hash(x)];
List p = find(x, H);
if (!p)
{
List tmp = (List)malloc(sizeof(Hashnode));
tmp->data = x;
tmp->cnt = ;
tmp->next = l->next;
l->next = tmp;
return false;
}
else
{
p->cnt++;
return true;
}
}
int main()
{
scanf("%d", &T);
HashTable H = Init();
while (T--)
{
clear(H);
scanf("%d", &n);
int ans = INF,tmp;
queue<int> q;
for (int i = ; i < n; i++)
{
scanf("%d", &tmp);
if (!Insert(tmp,H))
{
q.push(tmp);
ans = q.size();
}
else
{
q.push(tmp);
while (!q.empty()&&cnt(q.front(),H) > )
{
q.pop();
}
ans = min(ans,(int)q.size());
}
}
printf("%d\n", ans);
}
return ;
}做法2 离散化+ 尺取
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 1000044
#define INF 1000000009
#define eps 0.00000001
int T, n;
int a[MAXN], b[MAXN], cnt[MAXN];
int bsearch(int l, int r, int aim)
{
while (l <= r)
{
int mid = (l + r) / ;
if (b[mid] == aim)
{
return mid;
}
else if (b[mid] < aim)
{
l = mid + ;
}
else
r = mid - ;
}
}
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (int i = ; i < n; i++)
scanf("%d", &a[i]);
memcpy(b, a, sizeof(a));
memset(cnt, , sizeof(cnt));
sort(b, b + n);
int size = unique(b, b + n) - b;
for (int i = ; i < n; i++)
{
a[i] = bsearch(, size, a[i]);
}
//for (int i = 0; i < n; i++)
// cout << a[i] << endl;
int ans = n, l = , sum = ;
cnt[a[]] = ;
for (int r = ; r < n; r++)
{
while (sum == size)
{
cnt[a[l]]--;
if (cnt[a[l]] == ) sum--;
l++;
ans = min(ans, r - l + );
}
if (cnt[a[r]] == ) sum++;
cnt[a[r]]++;
}
printf("%d\n", ans);
}
return ;
}
子序列 NYOJ (尺取法+队列+hash) (尺取法+离散化)的更多相关文章
- POJ 3320 尺取法,Hash,map标记
1.POJ 3320 2.链接:http://poj.org/problem?id=3320 3.总结:尺取法,Hash,map标记 看书复习,p页书,一页有一个知识点,连续看求最少多少页看完所有知识 ...
- UVA 11019 Matrix Matcher(二维hash + 尺取)题解
题意:在n*m方格中找有几个x*y矩阵. 思路:二维hash,总体思路和一维差不太多,先把每行hash,变成一维的数组,再对这个一维数组hash变成二维hash.之前还在想怎么快速把一个矩阵的hash ...
- CF452F Permutations/Luogu2757 等差子序列 树状数组、Hash
传送门--Luogu 传送门--Codeforces 如果存在长度\(>3\)的等差子序列,那么一定存在长度\(=3\)的等差子序列,所以我们只需要找长度为\(3\)的等差子序列.可以枚举等差子 ...
- BZOJ2124: 等差子序列(树状数组&hash -> bitset 求是否存在长度为3的等差数列)
2124: 等差子序列 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 2354 Solved: 826[Submit][Status][Discuss ...
- bzoj 2124 等差子序列 树状数组维护hash+回文串
等差子序列 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 1919 Solved: 713[Submit][Status][Discuss] Desc ...
- 【BZOJ2124】等差子序列 树状数组维护hash值
[BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...
- 栈 队列 hash表 堆 算法模板和相关题目
什么是栈(Stack)? 栈(stack)是一种采用后进先出(LIFO,last in first out)策略的抽象数据结构.比如物流装车,后装的货物先卸,先转的货物后卸.栈在数据结构中的地位很重要 ...
- bzoj2124 等差子序列(树状数组+hash)
题意 给你一个1~n排列,问有没有一个等差数列(长度至少为3) 题解 我居然自己想到了正解. 但我最后写挂了,所以我又看了题解. 我们维护了一个以权值为下标的01序列. 我们扫描整个序列.对于每一个正 ...
- SSY的队列 hash+记忆化
题目描述 \(SSY\) 是班集体育委员,总喜欢把班级同学排成各种奇怪的队形,现在班级里有 \(N\) 个身高互不相同的同学,请你求出这 \(N\) 个人的所有排列中任意两个相邻同学的身高差均不为给定 ...
随机推荐
- springMVC与freemarker整合
准备好的环境:Maven工程整合好了ssm,即spring+springMVC+mybatis.接下来准备将springMVC与freemarker整合,以html文件为模板. 一,加入freemar ...
- [Swift通天遁地]六、智能布局-(8)布局框架的使用:多分辨率适配和横竖屏布局
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 点击文字弹出一个DIV层窗口代码 【或FORM表单 并且获取点击按钮的ID值】
点击不同按钮咨询不同的 专家 <?php for($i=1;$i<5;$i++){ $uid=$i; //用户ID ?> <a class="a_click" ...
- Coursera公开课-Machine_learing:编程作业7
这周的编程作业主要是两方面内容. 1.K-means聚类. 2.PCA(Principle Component Analys)主成分分析. 方式主要是通过对图像的聚类实现压缩图像,后来发现PCA也可以 ...
- 329 Longest Increasing Path in a Matrix 矩阵中的最长递增路径
Given an integer matrix, find the length of the longest increasing path.From each cell, you can eith ...
- scala的Map
package com.test.scala.test object MapTest { def main(args: Array[String]): Unit = { //定义一个不可变的map v ...
- OpenAMP简介
通常在AMP(非对称多处理)配置中,会采用在不同的处理核上运行不同的软件环境并执行各自的代码程序,各核心之间通力合作实现处理器性能的提升.在AMP系统中,所谓的主处理器通常是指最先启动且主要负责管理其 ...
- [ SHOI 2012 ] 随机树
\(\\\) \(Description\) 开始有一棵只有一个根节点的树.每次随机选择一个叶子节点,为他添上左右子节点,求: 生成一棵有\(N\)个叶节点的树,所有叶节点平均高度的期望. 生成一棵有 ...
- ndk书写位置的问题
defaultConfig { applicationId "com.chenql.helloandroidjni" minSdkVersion 22 targetSdkVersi ...
- Twisted web开发教程
最近在网上看到一篇twisted web开发文章,将它实践了一下,twisted 提供基本的url路由 和 控制器,模板与模型需要外部扩展 1.目录浏览 2.get请求 3.url路由 4.接受带参数 ...