• Educational Codeforces Round 24 题解


    A:

    考你会不会除法

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    int n,k;
    signed main(){
        scanf("%I64d%I64d",&n,&k);
        int t=n/(2*(k+1));
        printf("%I64d %I64d %I64d
    ",t,t*k,n-t*(k+1));
    }

    B:

    按照题意模拟

    竟然挂了三次......

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=105;
    int n,m,l[N],a[N],stk[N],top,vis[N];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d",&l[i]);
        }
        for(int i=2;i<=m;i++){
            int dis=(l[i]-l[i-1]+n)%n;
            if(dis==0)dis=n;
            if(!a[l[i-1]]||a[l[i-1]]==dis)a[l[i-1]]=dis;
            else {puts("-1");return 0;}
        }
        for(int i=1;i<=n;i++){
            if(!a[i])continue;
            if(!vis[a[i]])vis[a[i]]=1;
            else {puts("-1");return 0;}
        }
        for(int i=1;i<=n;i++)if(!vis[i])stk[++top]=i;
        for(int i=1;i<=n;i++){
            if(a[i])printf("%d ",a[i]);
            else printf("%d ",stk[top--]);
        }
    }

    C:

    四个方向搞一个前缀和  注意大于小于  加一减一   算没算上自己 等等细节

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=100050;
    int d,n,m,suml[N],sumr[N],sumu[N],sumd[N],cntl,cntr,cntu,cntd;
    struct Node{
        int x1,y1,x2,y2;Node(){}
        Node(int X1,int Y1,int X2,int Y2){x1=X1,y1=Y1,x2=X2,y2=Y2;}
    }node[N];
    int main(){
        scanf("%d%d%d",&d,&n,&m);
        for(int i=1;i<=d;i++){
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2),node[i]=Node(x1,y1,x2,y2);
        }scanf("%d%d%d%d",&cntl,&cntr,&cntu,&cntd);
        for(int i=1;i<=d;i++)
            suml[min(node[i].x1,node[i].x2)]++,sumr[max(node[i].x1,node[i].x2)]++,
            sumu[min(node[i].y1,node[i].y2)]++,sumd[max(node[i].y1,node[i].y2)]++;
        for(int i=1;i<=n;i++)suml[i]+=suml[i-1];
        for(int i=n;~i;i--)sumr[i]+=sumr[i+1];
        for(int i=1;i<=m;i++)sumu[i]+=sumu[i-1];
        for(int i=m;~i;i--)sumd[i]+=sumd[i+1];
        for(int i=1;i<=d;i++){
            int a=suml[max(node[i].x1,node[i].x2)-1],b=sumr[min(node[i].x1,node[i].x2)+1],
                c=sumu[max(node[i].y1,node[i].y2)-1],d=sumd[min(node[i].y1,node[i].y2)+1];
            node[i].x1!=node[i].x2?a--,b--:0;
            node[i].y1!=node[i].y2?c--,d--:0;
            if(a==cntl&&b==cntr&&c==cntu&&d==cntd){printf("%d
    ",i);exit(0);}
        }puts("-1");
    }

    D:

    筛一次 就好了   最后判一下出现的所有数

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    int n,a,c[1000500],num[1000500],vis[1000500];
    int main(){
        scanf("%d%d",&n,&a);
        for(int i=1;i<=n;i++){
            scanf("%d",&c[i]);
            if(c[i]!=a&&num[c[i]]<num[a])vis[c[i]]=1;
            num[c[i]]++;
            if(c[i]!=a&&num[c[i]]<num[a])vis[c[i]]=1;
        }
        if(!num[a]){printf("%d
    ",(a+1)%1000000);return 0;}
        for(int i=1;i<=n;i++){
            if(c[i]!=a&&num[c[i]]<num[a])vis[c[i]]=1;
            if(c[i]!=a&&!vis[c[i]]){printf("%d
    ",c[i]);return 0;}
        }
        puts("-1");
    }

    E:

    分解质因数 two pointers一发

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    int n,k,a[105],b[105],cnt,p[100050],tmp;
    void insert(int x,int y){
        for(int i=1;i<=cnt;i++)while(x%a[i]==0){
            if(!b[i]&&y==1)tmp++;
            if(y==-1&&b[i]==1)tmp--;
            b[i]+=y,x/=a[i];
        }
    }
    int main(){
        scanf("%d%d",&n,&k);
        int now=k;
        for(int i=2;i*i<=k;i++)if(now%i==0){
            a[++cnt]=i;
            while(now%i==0)now/=i,b[cnt]++;
        }
        if(now>1)a[++cnt]=now,b[cnt]=1;tmp=cnt;
        for(int i=1;i<=n;i++)scanf("%d",&p[i]);
        long long ans=0;
        for(int i=1,j=1;i<=n;i++){
            for(;j<=i;j++)insert(p[j],-1);
            for(;j<=n&&tmp;j++)insert(p[j],-1);
            if(!tmp)ans+=n-j+2;
            insert(p[i],1);
        }printf("%I64d
    ",ans);
    }

    F:

    三分答案  特判一下前几个数  后面的肯定是   一坨 加一个链

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    int cases,xx;
    int f(int x){return x*(x-1)/2;}
    signed main(){
        scanf("%I64d",&cases);
        while(cases--){
            scanf("%I64d",&xx);
            if(xx==1){puts("0");continue;}
            int l=0,r=xx,ans=0;
            while(l<r){
                int mid=(l+r)/2,edges=mid*(mid-1)/2,bridge=xx-mid;
                if(bridge>edges)l=mid+1,ans=max(ans,edges+bridge);
                else r=mid,ans=max(ans,2*bridge);
            }printf("%I64d
    ",ans);
        }
    }

    G:

    费用流

    拆点建图  

    i->i+n 连流量1 费用-1  流量ing 费用0

    记录上一个%7=i的数是谁

    记录每个数最后出现的位置

        for(int i=1;i<=n;i++)add(0,i,0,inf),add(i+n,T,0,inf),add(i,i+n,-1,1),add(i,i+n,0,inf);
        for(int i=1;i<=n;i++){
            if(pos[a[i]-1])add(pos[a[i]-1]+n,i,0,inf);
            if(pos[a[i]+1])add(pos[a[i]+1]+n,i,0,inf);
            if(lst[a[i]%7])add(lst[a[i]%7]+n,i,0,inf);
            pos[a[i]]=i,lst[a[i]%7]=i;
        }add(S=n*2+2,0,0,4);
    最后限制起点流出的流量是4
    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    #define mem(x,y) memset(x,y,sizeof(x))
    const int N=6050,M=3050*6050,inf=0x3f3f3f3f;
    int first[N],nxt[M],v[M],cost[M],edge[M],tot,n,a[N],S,T,vis[N],dis[N],with[N],minn[N],pos[M],lst[M],ans;
    void Add(int x,int y,int C,int E){cost[tot]=C,edge[tot]=E,v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
    void add(int x,int y,int C,int E){Add(x,y,C,E),Add(y,x,-C,0);}
    bool tell(){
        queue<int>q;q.push(S);
        mem(dis,0x3f),mem(with,0),mem(minn,0x3f),mem(vis,0);dis[S]=0;
        while(!q.empty()){
            int t=q.front();q.pop();vis[t]=0;
            for(int i=first[t];~i;i=nxt[i])
                if(dis[v[i]]>dis[t]+cost[i]&&edge[i]){
                    dis[v[i]]=dis[t]+cost[i],minn[v[i]]=min(minn[t],edge[i]),with[v[i]]=i;
                    if(!vis[v[i]])vis[v[i]]=1,q.push(v[i]);
                }
        }return dis[T]<inf;
    }
    int zeng(){
        for(int i=T;i!=S;i=v[with[i]^1])
            edge[with[i]]-=minn[T],edge[with[i]^1]+=minn[T];
        return minn[T]*dis[T];
    }
    int main(){
        memset(first,-1,sizeof(first));
        scanf("%d",&n),T=2*n+1;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)add(S,i,0,inf),add(i+n,T,0,inf),add(i,i+n,-1,1),add(i,i+n,0,inf);
        for(int i=1;i<=n;i++){
            if(pos[a[i]-1])add(pos[a[i]-1]+n,i,0,inf);
            if(pos[a[i]+1])add(pos[a[i]+1]+n,i,0,inf);
            if(lst[a[i]%7])add(lst[a[i]%7]+n,i,0,inf);
            pos[a[i]]=i,lst[a[i]%7]=i;
        }add(S=n*2+2,0,0,4);
        while(tell())ans+=zeng();
        printf("%d
    ",-ans);
    }
  • 相关阅读:
    在ubuntu下复制文件出现权限不够的解决方法
    Ubuntu安装ROS Melodic
    gedit文件操作
    Linux下强制删除文件和权限操作
    VMware Tools 继续运行脚本未能在虚拟机中成功运行 解决方式
    Linux解压命令
    Ubuntu 18.04.4 LTS(Bionic Beaver)安装
    Socket层实现系列 — send()类发送函数的实现
    iOS7 CookBook精彩瞬间(三)UIActivityViewController的基本使用及自定义Activity
    iOS7 CookBook精彩瞬间(二)NSSet、通过Subscript访问类成员等
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/7126727.html
Copyright © 2020-2023  润新知