• 9.18 题解?


    100+100+10=210 rank 1
    T1,醉了,考试时对拍平均1分钟一个错,真爽……暴力枚举约数判断就好了,从根dfs,当

    size[v]modD+1>D
    时 return;

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #define N 1000005
    using namespace std;
    
    int dd[100005],vis[100005],tot,n,ans;
    
    int e=1,head[N];
    struct edge{
        int u,v,next;
    }ed[2*N];
    void add(int u,int v){
        ed[e].u=u;ed[e].v=v;
        ed[e].next=head[u];head[u]=e++;
    }
    
    int fa[N],size[N];
    void dfs(int x){
        for(int i=head[x];i;i=ed[i].next){
            int v=ed[i].v;
            if(v==fa[x])continue;
            fa[v]=x; dfs(v);
            size[x]+=size[v];
        }size[x]++;
    }
    
    void divid(int x){
        for(int i=2;i*i<=x;i++){
            if(x%i==0){
                dd[++tot]=i;
                if(i*i!=x)dd[++tot]=x/i;
            }
        }
    }
    
    bool lose;
    void dfs1(int x,int p){
        if(lose==1)return;
        if(size[x]<=p)return;
        int r=1,ful=0;
        for(int i=head[x];i;i=ed[i].next){
            int v=ed[i].v;
            if(v==fa[x])continue;
            int mm=size[v]%p;
            if(mm){
                if(ful){lose=1;return;}
                else{
                    if((r+mm)<=p){
                        r+=mm;
                        if(r==p)ful=1;
                    }
                    else{lose=1;return;}
                }
            }
        }
        for(int i=head[x];i;i=ed[i].next){
            int v=ed[i].v;
            if(v==fa[x])continue;
            dfs1(v,p);
        }
    }
    bool check(int x){
        lose=0; dfs1(1,x);
        return !lose;
    }
    
    int main(){
        //freopen("test.in","r",stdin);
        //freopen("my.out","w",stdout);
        scanf("%d",&n);
        if(n==1){printf("1
    ");return 0;}
        divid(n); 
        sort(dd+1,dd+tot+1);
        for(int i=1,u,v;i<n;i++){
            scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        dfs(1);
        ans=2;
        for(int i=tot;i>=1;i--)
            if(check(dd[i]))ans++;
        printf("%d
    ",ans);
        return 0;
    }

    T2,二分,暴力判断,我是枚举1所在块的右端点,暴力往左拓展,再判断.

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #define N 50005
    using namespace std;
    int n,m,a[N],sum[N],maxt,ANS;
    bool check(int x){
        int i=n,be=1,en,now,u,tot;
        en=n;
        while(sum[en]+a[1]<=x)en--;
        tot=sum[en+1]+a[1];
        while(1){
            while(sum[1]-sum[be+1]+sum[en+1]<=x)be++;
            be--; tot=sum[en+1]+sum[1]-sum[be+1];
            u=1;now=be;
            while(now<en){
                for(i=now;i<=en+1&&sum[now+1]-sum[i+1]<=x;i++);
                now=i-1; u++;
                if(u>m)break;
            }
            if(u<=m)return 1;
            for(i=en+1;i<=n+1&&tot+a[be+1]-(sum[en+1]-sum[i])>x;i++);
            be++; en=i-1;
            if(en>n)break;
        }
        return 0;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            maxt=max(maxt,a[i]);
        }
        for(int i=n;i>=1;i--)sum[i]=sum[i+1]+a[i];
        int l=maxt,r=sum[1],mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(check(mid)){ANS=mid;r=mid-1;}
            else l=mid+1;
        }
        printf("%d
    ",ANS);
        return 0;
    }

    T3,对题意理解不到位,没有想到建图。。而且被老于放了波毒。
    建图+spfa

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #define N 55
    using namespace std;
    
    int e=1,head[N*N];
    struct edge{
        int u,v,w,next;
    }ed[2*8*N*N];
    void add(int u,int v,int w){
        ed[e].u=u; ed[e].v=v; ed[e].w=w;
        ed[e].next=head[u]; head[u]=e++;
    }
    
    
    int dx[8]={-2,-2,-1,-1,1,1,2,2},dy[8]={-1,1,-2,2,-2,2,-1,1};
    int n,m,a[N][N],id[N][N],sx,sy,tx,ty,tot;
    
    bool jj(int x,int y){
        if(x<=0||y<=0||x>n||y>m)return 0;
        return 1;
    }
    bool bo[N*N],vis[N][N];
    int qq[N*N],cnt;
    bool road[N*N][N*N];
    
    void dfs(int x,int y){
        for(int i=0;i<8;i++){
            int nx=x+dx[i],ny=y+dy[i];
            if(jj(nx,ny)&&a[nx][ny]==1&&!bo[id[nx][ny]]){
                bo[id[nx][ny]]=1;
                dfs(nx,ny);
            }
            if(jj(nx,ny)&&!a[nx][ny]&&!vis[nx][ny]){
                vis[nx][ny]=1;
                qq[++cnt]=id[nx][ny];
            }
        }
    }
    
    int dis[N*N],g[N*N];
    void spfa(){
        memset(bo,0,sizeof bo);
        memset(dis,0x3f,sizeof dis);
        int q[N*N],h=1,t=1;q[1]=id[sx][sy];
        g[id[sx][sy]]=1;dis[id[sx][sy]]=0;bo[id[sx][sy]]=1;
        while(h<=t){
            int x=q[h++];bo[x]=0;
            for(int i=head[x];i;i=ed[i].next){
                int v=ed[i].v;
                if(dis[v]==dis[x]+ed[i].w){
                    g[v]+=g[x];
                    if(!bo[v]){bo[v]=1;q[++t]=v;}
                }
                if(dis[v]>dis[x]+ed[i].w){
                    g[v]=g[x];
                    dis[v]=dis[x]+ed[i].w;
                    if(!bo[v]){bo[v]=1;q[++t]=v;}
                }
            }
        }
        if(dis[id[tx][ty]]==dis[0])printf("-1
    ");
        else printf("%d
    %d
    ",dis[id[tx][ty]]-1,g[id[tx][ty]]);
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
                if(a[i][j]==3){sx=i;sy=j;a[i][j]=0;}
                if(a[i][j]==4){tx=i;ty=j;a[i][j]=0;}
            }
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)id[i][j]=++tot;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(a[i][j])continue;
                for(int k=0;k<8;k++){
                    int x=i+dx[k],y=j+dy[k];
                    if(jj(x,y)&&!a[i][j])add(id[i][j],id[x][y],1);
                }
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)if(a[i][j]==1&&(!bo[id[i][j]])){
                memset(vis,0,sizeof vis); cnt=0;
                dfs(i,j); bo[id[i][j]]=1;
                for(int k=1;k<=cnt;k++)
                    for(int l=1;l<=cnt;l++)
                        if(!road[qq[k]][qq[l]]){
                            road[qq[k]][qq[l]]=1;road[qq[l]][qq[k]]=1;
                            add(qq[k],qq[l],1);add(qq[l],qq[k],1);
                        }
            }
        spfa();
        return 0;
    }

    考试真好。

  • 相关阅读:
    gulp编译sass
    Material Design学习
    js爬虫心得
    js爬虫
    angularjs
    sass心得
    矩阵与线性代数学习笔记
    2-SAT学习笔记
    一个有趣的题目【二分答案,2-SAT,线段树优化】
    vijos训练之——星辰大海中闪烁的趣题
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746667.html
Copyright © 2020-2023  润新知