zoukankan      html  css  js  c++  java
  • PKUSC 模拟赛 day1 下午总结

    下午到了机房之后又困又饿,还要被强行摁着看英文题,简直差评

    第一题是NOIP模拟赛的原题,随便模拟就好啦

    本人模拟功力太渣不小心打错了个变量,居然调了40多分钟QAQ

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
     
    const int maxn=100010;
    char s[10][maxn];
    int Num[maxn];
    int a,b,n,k,now;
     
    int check(int L,int R){
        int cnt=0;
        for(int i=1;i<=7;++i)for(int j=L;j<=R;++j)if(s[i][j]=='x')cnt++;
        if(cnt==7)return 1;
        if(cnt==9)return -1;
        if(cnt==11)return 7;
        if(cnt==23)return 8;
        if(cnt==20)return 0;
        if(cnt==14)return 4;
        if(cnt==19){
            if(s[5][L]=='x')return 2;
            if(s[2][L]=='x')return 5;
            return 3;
        }
        if(cnt==21){
            if(s[5][L]=='x')return 6;
            return 9;
        }return 0;
    }
    void Get_print(int L,int R,int k){
        if(k==0){
            for(int i=L;i<=R;++i)s[1][i]='x',s[7][i]='x';
            for(int i=2;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==L||j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==1){
            for(int i=1;i<=7;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==2){
            for(int i=L;i<=R;++i)s[1][i]=s[4][i]=s[7][i]='x';
            for(int i=2;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=5;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==L)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==3){
            for(int i=L;i<=R;++i)s[1][i]=s[4][i]=s[7][i]='x';
            for(int i=2;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=5;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==4){
            for(int i=1;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==L||j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=L;i<=R;++i)s[4][i]='x';
            for(int i=5;i<=7;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==5){
            for(int i=L;i<=R;++i)s[1][i]=s[4][i]=s[7][i]='x';
            for(int i=2;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==L)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=5;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==6){
            for(int i=L;i<=R;++i)s[1][i]=s[4][i]=s[7][i]='x';
            for(int i=2;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==L)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=5;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==R||j==L)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==7){
            for(int i=L;i<=R;++i)s[1][i]='x';
            for(int i=2;i<=7;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==8){
            for(int i=L;i<=R;++i)s[1][i]=s[4][i]=s[7][i]='x';
            for(int i=2;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==L||j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=5;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==R||j==L)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }
        if(k==9){
            for(int i=L;i<=R;++i)s[1][i]=s[4][i]=s[7][i]='x';
            for(int i=2;i<=3;++i){
                for(int j=L;j<=R;++j){
                    if(j==L||j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }
            for(int i=5;i<=6;++i){
                for(int j=L;j<=R;++j){
                    if(j==R)s[i][j]='x';
                    else s[i][j]='.';
                }
            }return;
        }return;
    }
    void print(int n){
        int len=0,u=n;
        if(!n)Num[++len]=0;
        else{while(n)Num[++len]=n%10,n/=10;}
        for(int i=len;i>=1;--i){
            int L=(len-i)*6+1,R=(len-i+1)*6-1;
            Get_print(L,R,Num[i]);
            for(int j=1;j<=7;++j)s[j][R+1]='.';
        }
        len=len*6-1;
        for(int i=1;i<=7;++i){
            for(int j=1;j<=len;++j){
                putchar(s[i][j]);
            }printf("
    ");
        }
        return;
    }
     
    int main(){
        for(int i=1;i<=7;++i)scanf("%s",s[i]+1);
        a=b=0;n=strlen(s[1]+1);k=(n+1)/6;
        now=0;
        for(int i=1;i<=k;++i){
            int L=(i-1)*6+1,R=i*6-1;
            int c=check(L,R);
            if(c==-1)a=now,now=0;
            else now=now*10+c;
        }b=now;
        b=a+b;
        print(b);
        return 0;
    }
    

    第二题考场上只想出了对a和b的处理方式,没有想出c的处理方式

    貌似c要用NTT,还是模任意质数的NTT,决定去学习一发(坑ing)

    第三题考场上并没有做出来,首先题目奇怪的输入保证了每个点的出度均为1,且图中只存在偶环

    我们不妨考虑什么样的点一定在集合内,显然如果他入度为0,那么一定在集合内

    那么这个点所能到达的点就一定不能选了,把这两个点删掉之后,原图会又出现一些入度为0的点

    这样重复若干次之后原图剩下的就只有偶环了,对于偶环我们任取二分图的一侧染色即可

    细节略多,自己画画图推一推也能把细节都推出来

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    const int maxn=200010;
    int n,u;
    int to[maxn];
    int deg[maxn];
    int vis[maxn];
    int ans[maxn],tot=0;
    queue<int>Q;
    void toposort(){
        for(int i=1;i<=n;++i)if(deg[i]==0)Q.push(i),vis[i]=1;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            int now=to[u];
            if(vis[now]!=-1)continue;
            vis[now]=0;
            int v=to[now];deg[v]--;
            if(deg[v]==0&&vis[v]==-1)vis[v]=1,Q.push(v);
        }return;
    }
    int main(){
        scanf("%d",&n);n<<=1;
        for(int i=1;i<=n;++i){
            scanf("%d",&u);
            to[i]=u;deg[u]++;
        }
        memset(vis,-1,sizeof(vis));
        toposort();
        for(int i=1;i<=n;++i){
            if(vis[i]==-1){
                if(i<=(n>>1))ans[++tot]=i;
            }else{
                if(vis[i])ans[++tot]=i;
            }
        }
        for(int i=1;i<=tot;++i){
            printf("%d",ans[i]);
            if(i==tot)printf("
    ");
            else printf(" ");
        }return 0;
    }
    

    第四题是BC的原题的弱化版

    一开始看错题以为求字典序最小的解结果各种挂QAQ

    如果这些数有奇数个,sum=中位数*数的数量

    如果有偶数个,sum=(首项+尾项)*数的数量/2

    都是乘法,枚举因子搞一搞就好啦

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    using namespace std;
     
    const int oo=0x7fffffff;
    int T,n;
    int L,len;
     
    void check(int i){
        int k=n/i;
        if(k&1){
            int now=(i-k/2);
            if(now>0){
                if(k<len&&k!=1)len=k,L=now;
            }
        }
        if(i&1){
            int now=((i>>1)-k+1);
            k<<=1;
            if(now>0){
                if(k<len&&k!=1)len=k,L=now;
            }
        }return;
    }
     
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            if(n==1){printf("IMPOSSIBLE
    ");continue;}
            if(n&1){
                printf("%d = ",n);
                printf("%d + %d
    ",n>>1,(n>>1)+1);
                continue;
            }
            int m=(int)(sqrt(n+0.5))+1;
            L=oo;len=oo;
            for(int i=1;i<=m;++i){
                if(n%i==0){
                    check(i);
                    if(i*i!=n)check(n/i);
                }
            }
            if(L==oo)printf("IMPOSSIBLE
    ");
            else{
                printf("%d = ",n);
                for(int i=0;i<len;++i){
                    printf("%d ",L+i);
                    if(i!=len-1)printf("+ ");
                }printf("
    ");
            }
        }return 0;
    }
    

    第五题首先如果一个轮子被影响,显然比例是第一个轮子的R和这个轮子的R的比

    关键是判断逆时针和顺时针,我们发现由于数据造的很好,不存在三个轮子互相相交的情况

    那么显然第一个是逆时针,第一个影响到的是顺时针,再影响到的是逆时针。。。BFS一遍即可

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
     
    const int maxn=1010;
    int T,n;
    int vis[maxn];
    struct C{
        double x,y,r;
    }c[maxn];
    int h[maxn],cnt=0;
    struct edge{
        int to,next;
    }G[2000010];
    queue<int>Q;
    int GCD(int a,int b){return b==0?a:GCD(b,a%b);}
    void add(int x,int y){
        cnt++;G[cnt].to=y;G[cnt].next=h[x];h[x]=cnt;
    }
    double dis(const C &A,const C &B){
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    void BFS(){
        Q.push(1);vis[1]=0;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            for(int i=h[u];i;i=G[i].next){
                int v=G[i].to;
                if(vis[v]!=-1)continue;
                vis[v]=(vis[u]^1);
                Q.push(v);
            }
        }return;
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            memset(vis,-1,sizeof(vis));
            for(int i=1;i<=n;++i)scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);
            memset(h,0,sizeof(h));cnt=0;
            for(int i=1;i<=n;++i){
                for(int j=i+1;j<=n;++j){
                    if(dis(c[i],c[j])<=c[i].r+c[j].r){
                        add(i,j);add(j,i);
                    }
                }
            }BFS();
            for(int i=1;i<=n;++i){
                if(vis[i]==-1)printf("not moving
    ");
                else{
                    int A=(int)(c[i].r+0.1),B=(int)(c[1].r+0.1);
                    int d=GCD(A,B);
                    A/=d;B/=d;
                    if(A==1)printf("%d ",B);
                    else printf("%d/%d ",B,A);
                    if(vis[i]==1)printf("counterclockwise
    ");
                    else printf("clockwise
    ");
                }
            }
        }return 0;
    }
    

    第六题我还能说些什么呢,数据范围貌似暴力都可以过去啦

    正常点的写法就是矩形面积并的裸题

    由于本人忘记了线段树上的标记怎么维护了思考了很久,差点就要写分块了

    (不过分块还是很好写的,捂脸。。)

    写分块的过程中就领悟了标记怎么维护QAQ,然后写成线段树跑的飞快

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #define eps 1e-4
    using namespace std;
     
    const int maxn=400010;
    int n,kase,cnt,m;
    double a,b,cc,d;
    double pos[maxn];
    struct Seg{
        double l,r,h;
        int type;
    }c[maxn];
    struct Seg_Tree{
        int cnt;
        double len;
    }t[maxn<<2];
    bool cmp(const Seg &A,const Seg &B){
        return A.h<B.h;
    }
    void build(int o,int L,int R){
        t[o].cnt=t[o].len=0;
        if(L==R)return;
        int mid=(L+R)>>1;
        build(o<<1,L,mid);
        build(o<<1,mid+1,R);
    }
    int Get_pos(double v,int L,int R){
        while(L<=R){
            int mid=(L+R)>>1;
            if(fabs(pos[mid]-v)<eps)return mid;
            else if(v<pos[mid])R=mid-1;
            else L=mid+1;
        }return 0;
    }
    void Get_len(int o,int L,int R){
        if(t[o].cnt)t[o].len=pos[R+1]-pos[L];
        else if(L==R)t[o].len=0;
        else t[o].len=t[o<<1].len+t[o<<1|1].len;
    }
    void UPD(int o,int L,int R,int x,int y,int v){
        if(L>=x&&R<=y){
            t[o].cnt+=v;
            Get_len(o,L,R);
            return;
        }
        int mid=(L+R)>>1;
        if(y<=mid)UPD(o<<1,L,mid,x,y,v);
        else if(x>mid)UPD(o<<1|1,mid+1,R,x,y,v);
        else {UPD(o<<1,L,mid,x,y,v);UPD(o<<1|1,mid+1,R,x,y,v);}
        Get_len(o,L,R);
    }
     
    int main(){
        while(scanf("%d",&n)==1){
            if(!n)break;
            kase++;cnt=0;
            for(int i=0;i<n;i++){
              scanf("%lf%lf%lf%lf",&a,&b,&cc,&d);
              cnt++;
              c[cnt].l=a;c[cnt].r=cc;c[cnt].h=b;c[cnt].type=1;
              pos[cnt]=a;
              cnt++;
              c[cnt].l=a;c[cnt].r=cc;c[cnt].h=d;c[cnt].type=-1;
              pos[cnt]=cc;
            }
            sort(c+1,c+cnt+1,cmp);
            sort(pos+1,pos+cnt+1);
            m=0;pos[0]=-1;
            for(int i=1;i<=cnt;++i){
                if(pos[i]!=pos[i-1])pos[++m]=pos[i];
            }
            build(1,1,m);
            double ans=0;
            for(int i=1;i<=cnt;++i){
                int L=Get_pos(c[i].l,1,m);
                int R=Get_pos(c[i].r,1,m)-1;
                if(L<=R)UPD(1,1,m,L,R,c[i].type);
                ans+=(c[i+1].h-c[i].h)*t[1].len;
            }
            printf("Test case #%d
    ",kase);
            printf("Total explored area: %.2lf
    
    ",ans);
        }return 0;
    }
    

    考试中较好的地方:这场考试并没有什么较好的地方

    考试中较差的地方:

    1、模拟居然需要调试!

    2、第三题应该多推导而不是直接套二分图的模型的

    3、第五题应该早点看,最后几分钟才写完,真是危险

    4、模板还是不熟练,矩形面积并居然差点忘掉

  • 相关阅读:
    Ajax技术
    java web中filter分析
    Async分析
    解释session
    XML相关知识
    开学第一课
    svn
    spa单页面应用(angular)
    angular
    webpack认识
  • 原文地址:https://www.cnblogs.com/joyouth/p/5499217.html
Copyright © 2011-2022 走看看