子序列

时间限制:3000 ms  |  内存限制:65535 KB
难度:5
 
描述

给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少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 ;
}

最新文章

  1. 洛谷10月月赛Round.3
  2. C#关键字ref和out
  3. Ubuntu 更改文件夹权限及chmod详细用法
  4. LDA-math-神奇的Gamma函数
  5. 【转】XML之命名空间的作用(xmlns)
  6. Android添加标题进度条
  7. 《Windows驱动开发技术详解》之Windows内存管理
  8. Java的代码风格
  9. 【性能测试工具】-SIEGE、HTTP_LOAD、WebBench、Apache-ab
  10. Android 基础:常用布局 介绍 &amp; 使用(附 属性查询)
  11. jQuery extend 方法使用 (转)
  12. async/await 的一些知识
  13. 2017-11-11 Sa Oct 消参
  14. Android图片采样缩放
  15. js实现复选框的全选、全不选和反选
  16. anguar6中 无法在Element上找到属性 (eg 原DOM的offsetTop)
  17. 【Selenium-WebDriver自学】Selenium-IDE工具特点(二)
  18. 采用PowerDesigner 设计数据库
  19. 树莓派指定静态IP
  20. leetcode 罗马数字转整数

热门文章

  1. PCB SQL Server 触发器应用实例
  2. Python机器学习算法 — K-Means聚类
  3. vue-router路由加载两种模式
  4. MySQL数据库笔记总结
  5. CSS------选择器-----------选择器的分组、属性选择器
  6. cmd bat 相对命令
  7. MYSQL创建用户和授权方法(测试mysql5.7)
  8. JavaScript:常用总结
  9. js 翻页
  10. [Windows Server 2012] IIS自带FTP配置方法