主序列 题解——2019.10.14
问题描述】
有一个主序列,以及另外m个序列。请你判断这些序列是否是主序列删除若
干个数字之后得到的。
【输入格式】
输入的第一行包含一个整数n,代表主序列的长度。接下来一行包含?个空
格分隔的整数,代表主序列。
第三行包含一个整数m,代表需要判断的序列个数。每个序列用两行描述,
第一行给出其长度li ,第二行包含li 个空格分隔的整数,代表这个序列。
【输出格式】
对于每个需要判断的序列,输出一行 Yes 或者 No,代表序列是否是由主序
列删除若干个数字后得到的。
【样例输入】
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
【样例输出】
Yes
No
Yes
No
暴力直接对比两个序列竟然有40分?!
震惊~
我的代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int b[1000005]; int t[1000005]; int a[1000005]; int k[1000005]; int n,T,N; bool flag; inline int read() { int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')w=-1; ch=getchar(); } while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48),ch=getchar(); return s*w; } int main() { freopen("seq.in","r",stdin); freopen("seq.out","w",stdout); N=read(); for(int i=1; i<=N; i++) a[i]=read(),b[a[i]]++; T=read(); while(T--) { memset(t,0,sizeof(t)); n=read(); flag=true; for(int i=1; i<=n; i++) { k[i]=read(); t[k[i]]++; if(b[k[i]]<t[k[i]]||!b[k[i]])flag=false; } if(flag) { int tot=1,haha=1; while(1) { if(k[tot]==a[haha]) { tot++,haha++; } else haha++; if(haha==N+1||tot==n+1)break; } if(tot!=n+1)flag=false; } if(flag)cout<<"Yes"; else cout<<"No"; cout<<'\n'; } fclose stdin; fclose stdout; return 0; } /* 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 */
思路的话
大概就是有点贪心的感觉了,,
感性理解一下
孙土蛋还是nb呀
#include <cstdio> #include <cstdlib> const int N = (int)1e6; // const int SIZE = (int)24e6; struct node { int p, s, next; } q[N + 1]; int s[N + 1], p[N + 1], st[N + 1], len[N + 1], h[N + 1], cnt = 0; int n, m; bool v[N + 1]; // char inbuf[SIZE], *ip = inbuf; // inline int read() { // int ret = 0; // while (*ip > '9' || *ip < '0') ++ip; // while (*ip >= '0' && *ip <= '9') ret = ret * 10 + *(ip++) - '0'; // return ret; // } inline void addnode(int x, int s, int p) { q[++cnt].s = s, q[cnt].p = p; q[cnt].next = h[x]; h[x] = cnt; } int main() { freopen("seq.in", "r", stdin); freopen("seq.out", "w", stdout); // fread(inbuf, sizeof(char), sizeof(char) * SIZE, stdin); scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", s + i); scanf("%d", &m); for (int i = 1, pos = 0; i <= m; ++i) { scanf("%d", &len[i]); st[i] = pos; for (int j = 0, cur; j < len[i]; ++j) scanf("%d", &p[pos++]); addnode(p[st[i]], i, st[i]); } for (int i = 1; i <= n; ++i) { if (!h[s[i]]) continue; int t = h[s[i]]; for (h[s[i]] = 0; t; t = q[t].next) { node c = q[t]; if (c.p == st[c.s] + len[c.s] - 1) v[c.s] = true; else addnode(p[c.p + 1], c.s, c.p + 1); } } for (int i = 1; i <= m; ++i) { if (v[i]) printf("Yes\n"); else printf("No\n"); } fclose(stdin); fclose(stdout); return 0; }