[二分查找] [luoguP3500] [POI2010] TES-Intelligence Test

题目描述

One of the tasks in the Byteotian Intelligence Test (BIT) is to cross out numbers from an initial sequence in such a way that leaves as a result certain given sequences.

Byteasar longs to become the IQ Master of Byteotia, but he is no good in this kind of tasks.

But since practice makes perfect, he intends to practise a lot.

So much in fact that he asks you to write a program that will facilitate the training by verifying his answers quickly.

Byteotian智力测试机构的一项工作就是按照一定的规则删除一个序列的数字,得到一个确定的数列。Byteasar很渴望成为Byteotian智力测试机构的主管,但是他在这个工作上做的并不好,俗话说熟能生巧,他打算做很多练习,所以他希望你写一个程序来快速判断他的答案是否正确。

输入输出格式

输入格式:

第一行为一个整数m(1<=m<=1000000)第二行包括m个用空格分开的整数ai(1<=ai<=1000000),组成了最初的序列,第三行为一个整数n(1<=n<=1000000),表示n个Byteasar经过一系列删除得到的序列,每个序列两行,第一行给出长度L(1<=L<=m),然后下一行为L个由空格分开的整数bi(1<=bi<=1000000)。

输出格式:

共n行,如果Byteasar的序列确实是由最初的序列删除一些数得到,就输出TAK,否则输出NIE。

输入输出样例

输入样例#1:
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
输出样例#1:
TAK
NIE
TAK
NIE

说明

题目简述:给定一个数串,和m个小数串,问这些小串都是不是大数字串的子序列

感谢@Yhy9630 提供翻译

 

俺的题解

建立大数字串的vector,内按从小到大的顺序存放每一个数字在此串中出现过的位置。输入时可循环求得。

对于每个小数串,如果它是子序列,每一位数字都需要依次在大数字串中出现。

所以,在线查询每个小数串,记录当前已确定的子序列最后一位在大数串中的位置为now,对于每个小串数字,二分查找所对应的大数字串的那个数字的vector,找vector中记录的位置大于等于now + 1中最小的(此时可以使用lower_bound)。

 

俺的代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 1000007;
 9 vector<int> t[maxn];
10 vector<int> :: iterator sh;
11 int n, m, a[maxn], b[maxn];
12 
13 int main()
14 {
15     scanf("%d", &m);
16     for(int i = 1; i <= m; i++)
17     {
18         int a;
19         scanf("%d", &a);
20         t[a].push_back(i);
21     }
22     int b;
23     scanf("%d", &n);
24     for(int i = 1; i <= n; i++)
25     {
26         int ll, now = 0; bool rt = 1; 
27         scanf("%d", &ll);
28         
29         for(int j = 1; j <= ll; j++)
30         {
31             scanf("%d", &b);
32             if(!rt)
33                 continue;
34             sh = lower_bound(t[b].begin(), t[b].end(), now + 1);
35             if(sh == t[b].end())
36                 rt = 0;
37             else
38                 now = *sh;
39         }
40         if(rt)
41             printf("TAK\n");
42         else
43             printf("NIE\n");
44     }
45     return 0;
46 }
点击就送屠龙宝刀

 

俺的反思

有明明可以在线操作,却用了空间的地方。

不仅浪费了空间,还tm用了memset = =,然后就超时了呢 = =

posted @ 2017-10-04 00:06  秃猴  阅读(267)  评论(0编辑  收藏  举报