9.18 题解?
来源:互联网 发布:大都会歌剧院 知乎 编辑:程序博客网 时间:2024/06/05 18:51
100+100+10=210 rank 1
T1,醉了,考试时对拍平均1分钟一个错,真爽……暴力枚举约数判断就好了,从根dfs,当
#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;}
考试真好。
阅读全文
0 0
- 9.18 题解?
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解~~~~
- 题解。。。。
- 题解
- 题解
- 1002 题解
- pku1001题解
- 全面解析所有的工厂模式!
- 使用CSS里的user-select属性控制用户在页面上选中的内容
- 多条目加载
- eclipse debug processWorkerExit(w, completedAbruptly)
- java8函数式接口和Lambda表达式应用在javaFX中tableView自定义点击事件
- 9.18 题解?
- python IDE(集成开发环境)
- JDBC创建连接的三种不同方式
- ARM 中可用性集使用的注意事项
- NFS响应超时处理
- HDU 2571 命运 【简单动态规划】
- 欢迎使用CSDN-markdown编辑器
- XML
- 关于 Sublime Text 3 清空缓存文件(之前打开的文件)