9.18 题解?

来源:互联网 发布:大都会歌剧院 知乎 编辑:程序博客网 时间:2024/06/05 18:51

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 1000005using 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\n");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\n",ans);    return 0;}

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

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#define N 50005using 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\n",ANS);    return 0;}

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

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#define N 55using 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\n");    else printf("%d\n%d\n",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;}

考试真好。

原创粉丝点击