题目描述:
霸中智力测试机构的一项工作就是按照一定的规则删除一个序列的数字,得到一个确定的数列。
Lyx很渴望成为霸中智力测试机构的主管,但是他在这个工作上做的并不好,俗话说熟能生巧,
他打算做很多练习,所以他希望你写一个程序来快速判断他的答案是否正确。
输入:
第一行为一个整数m(1<=m<=1000000)
第二行包括m个用空格分开的整数ai(1<=ai<=1000000),组成了最初的序列,
第三行为一个整数n(1<=n<=1000000),表示n个Lyx经过一系列删除得到的序列,
每个序列两行,第一行给出长度L(1<=L<=m),然后下一行为L个由空格分开的整数bi(1<=bi<=1000000)。
输出:
共n行,如果Lyx的序列确实是由最初的序列删除一些数得到,就输出TAK,否则输出NIE。
算法标签:(学长给的分类是)模拟,(sgx神犇说是)STL的使用
思路:
因为倘若数据范围真的给满,连输入都输不下,所以我们可以知道一定数据是不满的,(为此我还思考一会儿啊很气啊啊),于是我们可以用vector存下每个字符出现的位置,每次upper_bound定位每一个字符的最先位置,下一个再从当前位置继续往后找。其实是不难..可我就是不会STL的使用啊!
以下代码:
#include<bits/stdc++.h> #define il inline #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int N=1e6+5;int n,m,b[N],i;vector<int> v[N];vector<int>::iterator it; il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;} int main() { m=read();for(i=1;i<=m;i++)v[read()].push_back(i); int Q=read();while(Q--){ int l=read();for(i=1;i<=l;i++)b[i]=read();int now=0; for(i=1;i<=l;i++){ it=upper_bound(v[b[i]].begin(),v[b[i]].end(),now); if(it==v[b[i]].end()) break; now=*it; } if(i>l)puts("TAK"); else puts("NIE"); } return 0; }