zoukankan      html  css  js  c++  java
  • COJ574 数字序列

    试题描述
     
    霸中智力测试机构的一项工作就是按照一定的规则删除一个序列的数字,得到一个确定的数列。陈思同学很渴望成为霸中智力测试机构的主管,但是他在这个工作上做的并不好,俗话说熟能生巧,他打算做很多练习,所以他希望你写一个程序来快速判断他的答案是否正确。
    输入
    第一行为一个整数m(1<=m<=1000000),
    第二行包括m个用空格分开的整数ai(1<=ai<=1000000),组成了最初的序列,
    第三行为一个整数n(1<=n<=1000000),表示n个陈思经过一系列删除得到的序列,每个序列两行,第一行给出长度L(1<=L<=m),然后下一行为L个由空格分开的整数bi(1<=bi<=1000000)。
    输出
    共n行,如果陈思的序列确实是由最初的序列删除一些数得到,就输出TAK,否则输出NIE。
    输入示例
    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
    输出示例
    TAK
    NIE
    TAK
    NIE
    其他说明
    二分2083

    对每个权值建立位置的集合,如果用vector要写二分,如果用平衡树就直接lower_bound了。

    vector,用now表示当前位置+1,下同(3979ms)

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=1000010;
    vector<int> T[maxn];
    int main() {
        int n=read();
        rep(1,n) T[read()].push_back(i);
        int m=read();
        while(m--) {
            int k=read(),now=1,ok=1;
            rep(1,k) {
                int v=read();
                if(!T[v].size()||T[v][T[v].size()-1]<now) ok=0;
                else {
                    int l=0,r=T[v].size()-1,mid;
                    while(l<r) if(T[v][mid=l+r>>1]<now) l=mid+1; else r=mid;
                    now=T[v][l]+1;
                }
            }
            if(ok) puts("TAK");
            else puts("NIE");
        }
        return 0;
    }
    View Code

    偷懒用set结果T飞了(TLE)

    #include<cstdio>
    #include<cctype>
    #include<set>
    #include<cstring>
    #include<algorithm>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=1000010;
    set<int> T[maxn];
    set<int>::iterator it;
    int main() {
        int n=read();
        rep(1,n) T[read()].insert(i);
        int m=read();
        while(m--) {
            int k=read(),now=1,ok=1;
            rep(1,k) {
                int v=read();
                if(!T[v].size()) ok=0;
                else {
                    it=T[v].lower_bound(now);
                    if(it==T[v].end()) ok=0;
                    else now=(*it)+1;
                }
            }
            if(ok) puts("TAK");
            else puts("NIE");
        }
        return 0;
    }
    View Code

    STL太慢了,我们可以写一个数组,以权值为第一关键字,以位置为第二关键字排序,然后再上面继续二分。(827ms)

    我竟然又WA了一发,越来越感觉要直播了。

    #include<cstdio>
    #include<cctype>
    #include<set>
    #include<cstring>
    #include<algorithm>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=1000010;
    struct Arr {
        int p,v;
        bool operator < (const Arr& ths) const {
            if(v!=ths.v) return v<ths.v;
            return p<ths.p;
        }
    }A[maxn];
    int L[maxn],R[maxn];
    int main() {
        int n=read();
        rep(1,n) A[A[i].p=i].v=read();
        sort(A+1,A+n+1);
        int cur=1;
        rep(1,1000000) {
            if(A[cur].v!=i) continue;
            L[i]=cur;while(A[cur+1].v==i) cur++;R[i]=cur++;
        }
        int m=read();
        while(m--) {
            int k=read(),now=1,ok=1;
            rep(1,k) {
                int v=read();if(!L[v]||A[R[v]].p<now) ok=0;
                if(!ok) continue;
                int l=L[v],r=R[v],mid;
                while(l<r) if(A[mid=l+r>>1].p<now) l=mid+1; else r=mid;
                now=A[l].p+1;
            }
            if(ok) puts("TAK");
            else puts("NIE");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ORA-22835:缓冲区对于CLOB到CHAR转换而言太小
    C#发起Http请求,调用接口
    C#发起HTTP请求Post请求
    C# 调用HTTP接口两种方式Demo WebRequest/WebResponse 和WebApi
    SQL中的子查询
    C# 使用multipart form-data方式post数据到服务器
    批处理框架 Spring Batch 这么强,你会用吗
    JAVA基础(一)
    数据库---连接查询多表查询
    数据库---约束
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4630609.html
Copyright © 2011-2022 走看看