• 同志们的毒害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("
    ");}
    40     vis[n]=1;
    41     dfs(n,0,1); 
    42     printf("%.2lf",anss);
    43     return 0;
    44 }
    JOJO

        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("
    ");
    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;

      

  • 相关阅读:
    hdu 5119 Happy Matt Friends
    hdu 5128 The E-pang Palace
    hdu 5131 Song Jiang's rank list
    hdu 5135 Little Zu Chongzhi's Triangles
    hdu 5137 How Many Maos Does the Guanxi Worth
    hdu 5122 K.Bro Sorting
    Human Gene Functions
    Palindrome(最长公共子序列)
    A Simple problem
    Alignment ( 最长上升(下降)子序列 )
  • 原文地址:https://www.cnblogs.com/liuhailin/p/11399999.html
Copyright © 2020-2023  润新知