同志们的毒害1_xuhang01
Posted liuhailin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了同志们的毒害1_xuhang01相关的知识,希望对你有一定的参考价值。
在光老犇的迫害下,高二全体信奥成员 含泪 为自己的战友们出了一套题
xuhang01同学光荣成为第一位迫害人,出了一套科学且玄学的卷,照理水一发题解博客
链接: http://218.62.22.209:8080/contest.php?cid=2228
T1
二分求解,二分两棵树之间的最长距离,O(n)验证即可
但是跑之前要先sort一遍......
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,m,maxx; 4 int a[100010]; 5 bool check(int x) 6 int now=a[1],num=0; 7 for(register int i=2;i<=n;i++) 8 if(abs(a[i]-now)>=x) num++,now=a[i]; 9 if(num==m-1) return true; 10 11 return false; 12 13 int ef(int l,int r) 14 if(l==r) return l; 15 int mid=(l+r)/2; 16 if(check(mid+1)) ef(mid+1,r); 17 else ef(l,mid); 18 19 int main() 20 scanf("%d%d",&n,&m); 21 for(register int i=1;i<=n;i++) scanf("%d",&a[i]),maxx=max(a[i],maxx); 22 sort(a+1,a+n+1); 23 printf("%d",ef(1,maxx)); 24 return 0; 25
T2
模拟,每次插入新值时做判断,如果当前数位所放位置没被放,
更新被赋值点的赋值方向赋值,有被放过就更新所有的前后关系即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct node 4 int l,r; 5 a[1000010]; 6 int n,m,now=1,x,y; 7 bool vis[1000010]; 8 int main() 9 scanf("%d",&n); 10 for(register int i=2;i<=n;i++) 11 scanf("%d%d",&x,&y); 12 if(y==1) 13 if(!a[x].r) a[x].r=i,a[i].l=x; 14 else if(a[x].r) a[i].l=x,a[i].r=a[x].r,a[a[x].r].l=i,a[x].r=i; 15 16 17 else if(y==0) 18 if(!a[x].l) a[x].l=i,a[i].r=x; 19 if(x==now) now=i; 20 else if(a[x].l) a[i].r=x,a[i].l=a[x].l,a[a[x].l].r=i,a[x].l=i; 21 22 23 scanf("%d",&m); 24 for(register int i=1;i<=m;i++) scanf("%d",&x),vis[x]=1; 25 while(a[now].r) 26 if(!vis[now]) printf("%d ",now); 27 now=a[now].r; 28 29 if(!vis[now]) printf("%d",now); 30 return 0; 31
T3
全员连边,从(0,0)开始暴力搜索即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct node 4 double x,y; 5 a[100010]; 6 int n,cnt; 7 double turn(int q,int p) 8 double emm=sqrt(((double)(a[q].x-a[p].x)*(a[q].x-a[p].x))+((double)(a[q].y-a[p].y)*(a[q].y-a[p].y))); 9 return emm; 10 11 double anss=99999999; 12 double ans[20][20]; 13 bool vis[20]; 14 void dfs(int now,double now_ans,int num) 15 if(now_ans>anss) return; 16 if(num==n)anss=min(anss,now_ans);return; 17 for(register int i=1;i<=n;i++) 18 if(i==now) continue; 19 if(vis[i]) continue; 20 vis[i]=1; 21 dfs(i,now_ans+ans[now][i],num+1); 22 vis[i]=0; 23 24 25 int main() 26 scanf("%d",&n); 27 for(register int i=1;i<=n;i++) 28 scanf("%lf%lf",&a[i].x,&a[i].y); 29 for(register int j=1;j<i;j++) 30 ans[i][j]=ans[j][i]=turn(i,j); 31 32 33 a[n+1].x=0,a[n+1].y=0; 34 for(register int i=1;i<=n;i++) 35 ans[n+1][i]=ans[i][n+1]=turn(n+1,i); 36 37 n++; 38 // for(register int i=1;i<=n;i++) 39 // for(register int j=1;j<=n;j++) printf("%.2lf ",ans[i][j]);printf("\n"); 40 vis[n]=1; 41 dfs(n,0,1); 42 printf("%.2lf",anss); 43 return 0; 44
T4
先初始化好一个倒着的答案,占用4*4空间,然后每n++就向右复制一遍
再向下面的中间位置复制一遍,同时更新空间占用情况即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 char a[3000][3000]; 4 int n,now=4,k=1; 5 int main() 6 scanf("%d",&n); 7 memset(a,‘ ‘,sizeof(a)); 8 a[1][1]=a[2][2]=‘/‘; 9 a[1][2]=a[1][3]=‘_‘; 10 a[1][4]=a[2][3]=‘\\‘; 11 while(k<n) 12 for(register int i=1;i<=now/2;i++) 13 for(register int j=1;j<=now;j++) 14 a[i+now/2][j+now/2]=a[i][j+now]=a[i][j]; 15 now*=2,k++; 16 17 for(int i=now/2;i>=1;i--) 18 for(int j=1;j<=now;j++) printf("%c",a[i][j]); 19 printf("\n"); 20 21 return 0; 22
T5
咕咕咕.....
T6
输入时建边,星门对准的边边权为0,其他的边边权为1,
跑一遍最短路即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[110][110]; 4 int n,st,en,m,x; 5 int maxx=99999999; 6 int main() 7 scanf("%d%d%d",&n,&st,&en); 8 for(register int i=1;i<=n;i++) 9 for(register int j=1;j<=n;j++) 10 if(i==j) a[i][j]=0; 11 else a[i][j]=maxx; 12 for(register int i=1;i<=n;i++) 13 scanf("%d",&m); 14 for(register int j=1;j<=m;j++) 15 scanf("%d",&x); 16 if(j==1)a[i][x]=0;continue; 17 a[i][x]=1; 18 19 20 for(register int i=1;i<=n;i++) 21 for(register int j=1;j<=n;j++) 22 for(register int k=1;k<=n;k++) 23 a[j][k]=min(a[j][k],a[j][i]+a[i][k]); 24 25 if(a[st][en]==maxx) printf("-1"); 26 else printf("%d",a[st][en]); 27 return 0; 28
T7
首先理解题意,如果能用2的k次方跑到终点答案即1,每多一个二进制
数ans++,同样我们先Floyd初始化,然后再在Floyd外层加一层,判断2进制数
的循环更新答案即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[110][110]; 4 bool vis[110][110][50]; 5 int n,m,x,y; 6 int main() 7 memset(a,0x3f,sizeof(a)); 8 scanf("%d%d",&n,&m); 9 for(register int i=1;i<=m;i++) scanf("%d%d",&x,&y),a[x][y]=1,vis[x][y][0]=1; 10 for(register int i=1;i<=n;i++) a[i][i]=0; 11 12 for(register int i=1;i<=30;i++) 13 for(register int j=1;j<=n;j++) 14 for(register int k=1;k<=n;k++) 15 for(register int g=1;g<=n;g++) if(vis[j][k][i-1]&&vis[k][g][i-1]) vis[j][g][i]=1,a[j][g]=1; 16 17 for(register int i=1;i<=n;i++) 18 for(register int j=1;j<=n;j++) 19 for(register int k=1;k<=n;k++) a[j][k]=min(a[j][k],a[j][i]+a[i][k]); 20 21 printf("%d",a[1][n]); 22 return 0; 23
end;
以上是关于同志们的毒害1_xuhang01的主要内容,如果未能解决你的问题,请参考以下文章