首页 > ACM题库 > HDU-杭电 > hdu 2158 最短区间版大家来找碴-模拟-[解题报告]C++
2013
12-30

hdu 2158 最短区间版大家来找碴-模拟-[解题报告]C++

最短区间版大家来找碴

问题描述 :

给定一个序列,有N个整数,数值范围为[0,N)。
有M个询问,每次询问给定Q个整数,可能出现重复值。
要求找出一个最短区间,该区间要包含这Q个整数数值。
你能找的出来吗?

输入:

第一行有两个整数N,M。(N<100000, M<1000)接着一行有N个整数。再有M个询问,每个询问的第一行有一个整数Q(Q<100),第二行跟着Q个整数。当N,M同时为0时,输入结束。

输出:

第一行有两个整数N,M。(N<100000, M<1000)接着一行有N个整数。再有M个询问,每个询问的第一行有一个整数Q(Q<100),第二行跟着Q个整数。当N,M同时为0时,输入结束。

样例输入:

5 2
1 2 2 3 1
3
1 2 3
3
1 1 3
0 0

样例输出:

3
2

Hint
第二个查询,找到的区间是[4,5]

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std;

const int MAX=100000+10;
int s[MAX],num[MAX],pos[MAX];//pos记录i的第一个位置
int mark[MAX];

int main(){
	int n,m,q,a;
	while(cin>>n>>m,n+m){
		memset(mark,0,sizeof mark);
		memset(pos,-1,sizeof pos);
		for(int i=0;i<n;++i){
			scanf("%d",&s[i]);
			if(pos[s[i]] == -1)pos[s[i]]=i;
		}
		s[n]=n;
		for(int i=1;i<=m;++i){
			scanf("%d",&q);
			int l=n,r=-1,maxlen=INF;
			for(int j=0;j<q;++j){
				scanf("%d",&a);
				num[a]=0;
				mark[a]=i;
				if(pos[a]>r)r=pos[a];
				if(pos[a]<l)l=pos[a];
			}
			for(int j=l;j<=r;++j)++num[s[j]];
			maxlen=r-l+1;
			while(r<n){
				--num[s[l]];
				if(num[s[l]] == 0){
					while(++r<n && s[r] != s[l])++num[s[r]];//维护r时区间[l,r]包含m个数 
					num[s[r]]=1;
				}
				while(++l<=r && mark[s[l]] != i);//l每次都到下一个输入过的点 
				if(r<n && maxlen>r-l+1)maxlen=r-l+1;
			}
			cout<<maxlen<<endl;
		}
	}
	return 0;
}

解题转自:http://blog.csdn.net/xingyeyongheng/article/details/9787505


  1. A猴子认识的所有猴子和B猴子认识的所有猴子都能认识,这句话用《爱屋及乌》描述比较容易理解……

  2. 第2题,TCP不支持多播,多播和广播仅应用于UDP。所以B选项是不对的。第2题,TCP不支持多播,多播和广播仅应用于UDP。所以B选项是不对的。

  3. 在方法1里面:

    //遍历所有的边,计算入度
    for(int i=0; i<V; i++)
    {
    degree = 0;
    for (j = adj .begin(); j != adj .end(); ++j)
    {
    degree[*j]++;
    }
    }

    为什么每遍历一条链表,要首先将每个链表头的顶点的入度置为0呢?
    比如顶点5,若在顶点1、2、3、4的链表中出现过顶点5,那么要增加顶点5的入度,但是在遍历顶点5的链表时,又将顶点5的入度置为0了,那之前的从顶点1234到顶点5的边不是都没了吗?

  4. 我还有个问题想请教一下,就是感觉对于新手来说,递归理解起来有些困难,不知有没有什么好的方法或者什么好的建议?