BZOJ2083: [Poi2010]Intelligence test

Description

霸中智力測試機構的一項工作就是按照一定的規則刪除一個序列的數字,得到一個確定的數列。Lyx很渴望成爲霸中智力測試機構的主管,但是他在這個工作上做的並不好,俗話說熟能生巧,他打算做很多練習,所以他希望你寫一個程序來快速判斷他的答案是否正確。

Input

第一行爲一個整數m(1<=m<=1000000)第二行包括m個用空格分開的整數ai(1<=ai<=1000000),組成了最初的序列,第三行爲一個整數n(1<=n<=1000000),表示n個Lyx經過一系列刪除得到的序列,每個序列兩行,第一行給出長度L(1<=L<=m),然後下一行爲L個由空格分開的整數bi(1<=bi<=1000000)。

Output

共n行,如果Lyx的序列確實是由最初的序列刪除一些數得到,就輸出TAK,否則輸出NIE。

Sample Input

7
1 5 4 5 7 8 6
4
5
1 5 5 8 6
3
2 2 2
3
5 7 8
4
1 5 7 4

Sample Output

TAK
NIE
TAK
NIE


題解:

  題目大意爲給定n個數,每次給定一個序列,問這個序列是否爲給定的原序列的一個子序列(不要求連續)。

   這道題很容易想到二分。按照權值做一個vector,每次來一個新數,判斷數在序列的位置並記錄下last(因爲序列是有順序的),如果找不到,就返回false

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int MAXN=1000001;
int a[MAXN];
vector <int> S[MAXN];
vector <int> ::iterator it;
int main(int argc, char *argv[])
{
	int n,i,j,x,m,l,r,mid,len,t,last;
	bool flag;
	scanf("%d",&m);
	for(i=1;i<=m;i++)
	scanf("%d",&a[i]),S[a[i]].push_back(i);
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		flag=true;
		scanf("%d",&len);
		l=0,r=m,last=0;
		for(j=1;j<=len;j++)
		{
			scanf("%d",&x);
			if(flag==false) continue;
			if(S[x].empty()) {
				flag=false;
				continue;
			}
			it=upper_bound(S[x].begin(),S[x].end(),last);
			if(it==S[x].end()) flag=false;
			last=*it;
		}
		if(flag==false) printf("NIE\n");
		else printf("TAK\n");
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章