zoukankan      html  css  js  c++  java
  • codeforces Educational Round 37(部分题解)

    比赛的时候只过了ABC题,F题爆了三发,TLE,后来发现F题把<=1改成<=2就A了,┭┮﹏┭┮

    A:n个格子,k个有水,每次有水的格子会往左右倒水,问多少轮后所有格子都有水。

    题解:模拟。。

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #define mp make_pair
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pa;
    const int N=206;
    int n,a[N];
    bool b[N],c[N];
    int Write[20],WRI;
    void judge(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
    int read(){int d=0,f=1; char c=getchar(); while (c<'0'||c>'9'){if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=d*10+c-48,c=getchar(); return d*f;}
    void write(int x){if (!x){putchar('0'); return;}if (x<0) putchar('-'),x=-x;for (WRI=1;x;x/=10,WRI++) Write[WRI]=x%10;for (int i=WRI-1;i;i--) putchar((char)(Write[i]+48));}
    int main()
    {
        //judge();
        int T=read();
        while (T--)
        {
            n=read(); int k=read();
            for (int i=1;i<=200;i++) b[i]=0;
            for (int i=1;i<=k;i++) b[read()]=1;
            int ans=0;
            for (;;ans++)
            {
                bool bo=1;
                for (int i=1;i<=n;i++) if (!b[i]) bo=0; 
                if (bo) break;
                for (int i=1;i<=n;i++)
                    if (b[i])
                    {
                        if (i-1) c[i-1]=1;
                        if (i+1<=n) c[i+1]=1;
                        c[i]=1;
                    }
                for (int i=1;i<=n;i++) b[i]=c[i],c[i]=0;
            }
            printf("%d
    ",ans+1);
        }
        return 0;
    }
    View Code

    B:有n(n<=1000)个学生,第i个学生在l[i]时刻来到queue最后,同一时刻来的学生编号小的在前,每个时刻队头的学生能拿到tea,若第i个学生r[i]时刻不能拿到tea,他就会离开队伍。问每个学生拿到tea的时刻(不能拿到的输出0)

    题解:一开始没想清楚就写了,WA,改完后发现自己是个ZZ,也算是模拟题吧。。。

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #define mp make_pair
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pa;
    const int N=1010;
    struct node{int x,y,id;}a[N];
    int n,T,h,t,q[N],ans[N];
    int Write[20],WRI;
    void judge(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
    int read(){int d=0,f=1; char c=getchar(); while (c<'0'||c>'9'){if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=d*10+c-48,c=getchar(); return d*f;}
    void write(int x){if (!x){putchar('0'); return;}if (x<0) putchar('-'),x=-x;for (WRI=1;x;x/=10,WRI++) Write[WRI]=x%10;for (int i=WRI-1;i;i--) putchar((char)(Write[i]+48));}
    bool cmp(node a,node b){return a.x<b.x||a.x==b.x&&a.id<b.id;}
    int main()
    {
        //judge();
        int T=read();
        while (T--)
        {
            n=read();
            memset(a,0,sizeof a);
            memset(q,0,sizeof q);
            for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
            for (int i=1;i<=n;i++) a[i].id=i;
            sort(a+1,a+1+n,cmp);
            int tt=a[1].x; bool bo=0;
            for (int p=1;p<=n;p++)
            {
                int x=p;
                if (tt>a[x].y) ans[x]=0;
                else
                {
                    if (tt<a[x].x) tt=a[x].x;
                    ans[x]=tt;
                    tt++;
                }
            }
            for (int i=1;i<=n;i++) printf("%d ",ans[i]); puts("");
        }
        return 0;
    }
    View Code

    C:给一个n个数的排列(n<=200000),告诉你每个位置能否与后一位交换,问能否通过若干次交换使序列有序。

    题解:从大到小枚举,可行的话必须要这个数当前位置到应在位置-1都是可交换的,做完了。

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #define mp make_pair
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pa;
    const int N=200010;
    int n,a[N],b[N],sum[N];
    char s[N];
    int Write[20],WRI;
    void judge(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
    int read(){int d=0,f=1; char c=getchar(); while (c<'0'||c>'9'){if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=d*10+c-48,c=getchar(); return d*f;}
    void write(int x){if (!x){putchar('0'); return;}if (x<0) putchar('-'),x=-x;for (WRI=1;x;x/=10,WRI++) Write[WRI]=x%10;for (int i=WRI-1;i;i--) putchar((char)(Write[i]+48));}
    int main()
    {
        //judge();
        n=read();
        for (int i=1;i<=n;i++) a[i]=read(),b[a[i]]=i;
        scanf("%s",s+1);
        for (int i=n;i>=1;i--) sum[i]=sum[i+1]+s[i]-'0';
        for (int i=n;i>=1;i--)
            if (i>b[i]&&sum[b[i]]-sum[i]!=i-b[i])
            {
                puts("NO");
                return 0;
            }
        puts("YES");
        return 0;
    }
    View Code

    E:有一个n个点m条边的无向图,求其补图的联通块个数及每个块的大小(n,m<=200000)

    题解:bfs,每次bfs时,设u=q.front(),将原图中与u相连的点标记为与u相连,这样剩下的点就是补图中与u相连的点,将它们加入联通块和队列,用链表优化。

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #define mp make_pair
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pa;
    const int N=200010;
    struct E{int to,nxt;}e[N<<1];
    int n,m,head[N],cnt,l[N],r[N],ans[N],ans_cnt,fa[N];
    bool b[N];
    int Write[20],WRI;
    void judge(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
    int read(){int d=0,f=1; char c=getchar(); while (c<'0'||c>'9'){if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=d*10+c-48,c=getchar(); return d*f;}
    void write(int x){if (!x){putchar('0'); return;}if (x<0) putchar('-'),x=-x;for (WRI=1;x;x/=10,WRI++) Write[WRI]=x%10;for (int i=WRI-1;i;i--) putchar((char)(Write[i]+48));}
    void add(int x,int y){e[++cnt]=(E){y,head[x]}; head[x]=cnt;}
    void addedge(int x,int y){add(x,y); add(y,x);}
    void del(int x){b[x]=1; r[l[x]]=r[x]; l[r[x]]=l[x];}
    void bfs(int ljj)
    {
        queue<int>q;
        int sum=1;
        q.push(ljj);
        while (!q.empty())
        {
            int u=q.front(); q.pop();
            for (int i=head[u];i;i=e[i].nxt)
            {
                int v=e[i].to;
                fa[v]=u;
            }
            for (int i=r[0];i<=n;i=r[i])
                if (fa[i]!=u&&!b[i])
                {
                    q.push(i);
                    del(i);
                    sum++;
                }
        }
        ans[++ans_cnt]=sum;
    }
    int main()
    {
        //judge();
        n=read(); m=read();
        for (int i=1;i<=m;i++) addedge(read(),read());
        for (int i=0;i<=n;i++) l[i]=i-1,r[i]=i+1;
        for (int i=1;i<=n;i=r[i]) if (!b[i]) 
        {
            del(i);
            bfs(i);
        }
        sort(ans+1,ans+1+ans_cnt);
        write(ans_cnt); puts("");
        for (int i=1;i<=ans_cnt;i++) write(ans[i]),putchar(' ');
        return 0;
    }
    View Code

    F:设D(n)表示n的因数个数,给n个数,q次操作,1 l r表示将[l,r]的每个数a[i]变为D(a[i]),2 l r表示输出sum(l,r)。(n,q<=3E5,a[i]<=1E6)

    题解:套路题,线段树,x变为D(x)的次数不会很多,修改就暴力下去,每个节点记录其代表区间是否全部<=2,遇到标记了的区间就不用下去了,查询直接做。比赛的时候脑子不清楚,写了<=1,愉快地T了。。。

    #include<cstdio>
    typedef long long LL;
    const int N=300010,M=1000010;
    struct node{int l,r; LL s; bool b;}a[N<<2];
    int n,m,f[M];
    int Write[20],WRI;
    inline int read(){int d=0,f=1; char c=getchar(); while (c<'0'||c>'9'){if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') d=d*10+c-48,c=getchar(); return d*f;}
    inline void write(LL x){if (!x){putchar('0'); return;}if (x<0) putchar('-'),x=-x;for (WRI=1;x;x/=10,WRI++) Write[WRI]=x%10;for (int i=WRI-1;i;i--) putchar((char)(Write[i]+48));}
    inline void build(int i,int l,int r)
    {
        a[i].l=l; a[i].r=r; a[i].b=0;
        if (l==r) {a[i].s=read(); if (a[i].s<=2) a[i].b=1; return;}
        int mid=(l+r)>>1;
        build(i<<1,l,mid); build(i<<1|1,mid+1,r);
        a[i].s=a[i<<1].s+a[i<<1|1].s;
        a[i].b=a[i<<1].b&&a[i<<1|1].b;
    }
    inline void update(int i,int l,int r)
    {
        if (a[i].b) return;
        if (a[i].l==a[i].r) {a[i].s=f[a[i].s]; if (a[i].s<=2) a[i].b=1; return;}
        int mid=(a[i].l+a[i].r)>>1;
        if (r<=mid) update(i<<1,l,r);
        else if (l>mid) update(i<<1|1,l,r);
        else update(i<<1,l,mid),update(i<<1|1,mid+1,r);
        a[i].s=a[i<<1].s+a[i<<1|1].s;
        a[i].b=a[i<<1].b&&a[i<<1|1].b;
    }
    inline LL query(int i,int l,int r)
    {
        if (l<=a[i].l&&a[i].r<=r) return a[i].s;
        int mid=(a[i].l+a[i].r)>>1;
        if (r<=mid) return query(i<<1,l,r);
        else if (l>mid) return query(i<<1|1,l,r);
        else return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
    }
    int main()
    {
        n=read(); m=read();
        for (int i=1;i<=1000000;i++)
            for (int j=1;i*j<=1000000;j++)
                f[i*j]++;
        build(1,1,n);
        while (m--)
        {
            int op=read(),l=read(),r=read();
            if (op==1) update(1,l,r);
            else printf("%lld
    ",query(1,l,r));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    通过POST请求上传文件
    接口测试及常用接口测试工具
    maven-surefire-plugin插件
    BDD框架之Cucumber研究
    一分钟认识:Cucumber框架
    ACM团队周赛题解(3)
    C++11新增容器以及元组
    ACM团队周赛题解(2)
    C++11部分特性
    ACM团队周赛题解(1)
  • 原文地址:https://www.cnblogs.com/lujiaju6555/p/8430573.html
Copyright © 2011-2022 走看看