主序列 题解——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<<'
';
    }
    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
*/
View Code

思路的话

大概就是有点贪心的感觉了,,

感性理解一下

孙土蛋还是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
");
        else printf("No
");
    }
    
    fclose(stdin);
    fclose(stdout);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ydclyq/p/11673296.html