• 大一训练赛20181105-二分三分分治部分


      A题-二分枚举C看是否满足即可,注意真实有可能会出现除0以及出现速度为负值,应该加以判断,舍去。由于C可能很大,或者很小建议开到+-1e9范围。

     1 #include<iostream>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<stdio.h>
     5 #include<math.h>
     6 using namespace std;
     7 struct node{
     8   int d,s;
     9 }a[1005];
    10 int n,t;
    11 double ans;
    12 int check(double s)
    13 {
    14    double time=0;
    15    for(int i=1;i<=n;i++){
    16       time+=a[i].d*1.0/(a[i].s+s);
    17       if (a[i].s+s<0)return 0;
    18    }
    19    if (time>t)return 0;
    20    else return 1;
    21    return 1;
    22 }
    23 
    24 void fen(double l,double r)
    25 {
    26     if(r-l>0.00000001)
    27     {
    28         double mid=(l+r)/2;
    29         if (check(mid))
    30         {
    31             ans=mid;
    32             fen(l,mid);
    33         }
    34         else
    35         {
    36             fen(mid,r);
    37         }
    38     }
    39     return;
    40 }
    41 int main()
    42 {
    43     while(~scanf("%d%d",&n,&t))
    44     {
    45         double l=-1e9,r=1e9;
    46         for (int i=1;i<=n;i++){
    47     
    48             scanf("%d%d",&a[i].d,&a[i].s);
    49         }
    50         fen(l,r);
    51         printf("%.9f
    ",ans);
    52     }
    53     return 0;
    54 }
    View Code

      B题-利用前缀和保存字符对x,y坐标的贡献,然后去二分最短的区间,然后判段这一段的区间是否满足,满足条件就是我需要走的步数是小于等于我这段区间的长度,并且剩下的必须是偶数步。

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxx = 2e5+10;
     7 int n;
     8 int x,y;
     9 char s[maxx];
    10 int a[maxx];
    11 int b[maxx];
    12 int ans=-1;
    13 bool check(int len)
    14 {
    15     for (int i=1; i+len-1<=n; i++)
    16     {
    17         int xx = a[n] - a[i+len-1] + a[i-1];
    18         int yy = b[n] - b[i+len-1] + b[i-1];
    19         int tx = x-xx;
    20         int ty = y-yy;
    21         if (abs(tx)+abs(ty)<=len && (len-abs(tx)-abs(ty))%2==0)
    22             return true;
    23     }
    24     return false;
    25 }
    26 void fen(int l,int r)
    27 {
    28     int mid = (l+r)/2;
    29     if (l<=r)
    30     {
    31         if (check(mid))
    32         {
    33             ans=mid;
    34             fen(l,mid-1);
    35         }
    36         else
    37         {
    38             fen(mid+1,r);
    39         }
    40     }
    41 }
    42 int main()
    43 {
    44     while(~scanf("%d",&n))
    45     {
    46         scanf("%s",s+1);
    47         scanf("%d%d",&x,&y);
    48         a[0]=0;
    49         b[0]=0;
    50         for (int i=1; i<=n; i++)
    51         {
    52             if(s[i]=='R')
    53             {
    54                 a[i]=a[i-1]+1;
    55                 b[i]=b[i-1];
    56             }
    57             else if (s[i]=='L')
    58             {
    59                 a[i]=a[i-1]-1;
    60                 b[i]=b[i-1];
    61             }
    62             else if (s[i]=='U')
    63             {
    64                 a[i]=a[i-1];
    65                 b[i]=b[i-1]+1;
    66             }
    67             else
    68             {
    69                 a[i]=a[i-1];
    70                 b[i]=b[i-1]-1;
    71             }
    72         }
    73          ans=-1;
    74         fen(0,n);
    75         printf("%d
    ",ans);
    76     }
    77     return 0;
    78 }
    View Code

      C题-二分答案即可

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 using namespace std;
     5 int m,n;
     6 int a[100005];
     7 bool check(int mid)
     8 {
     9     int num=0;
    10     for (int i=1; i<=m; i++)
    11     {
    12         num++;
    13         int j=i;
    14         int res=0;
    15         while (j<=m)
    16         {
    17             res+=a[j];
    18             if (res>mid)
    19             {
    20                 j--;
    21                 break;
    22             }
    23             j++;
    24         }
    25         i=j;
    26     }
    27     return(num<=n);
    28 }
    29 
    30 int main()
    31 {
    32     while(~scanf("%d%d",&m,&n))
    33     {
    34         int sum=0;
    35         int maxx = 0;
    36         for (int i=1; i<=m; i++)
    37         {
    38             scanf("%d",&a[i]);
    39             maxx=max(maxx,a[i]);
    40             sum=sum+a[i];
    41         }
    42         int res=0;
    43         int l=maxx;
    44         int r=sum;
    45         int mid;
    46         while (l<=r)
    47         {
    48             mid=(l+r)/2;
    49             if (check(mid))
    50             {
    51                 res=mid;
    52                 r=mid-1;
    53             }
    54             else
    55             {
    56                 l=mid+1;
    57             }
    58         }
    59         printf("%d
    ",res);
    60     }
    61   return 0;
    62 }
    View Code

      D题-贪心+二分答案判断即可。让每个位置的值尽可能的小,同时保证要大于前一个,因此当这个值能降到前一个值+1的情况,就变成a[i]=a[i]+1,如果能降到最小大于前一个,就降到最小,否则不合理。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int ans;
    int a[100007];
    int b[100007];
    int n;
    bool check(int x)
    {
        for (int i=1; i<=n; i++)
        {
            if (i==1)
            {
                b[i]=a[i]-x;
            }
            else
            {
                if (b[i-1]+1>=a[i]-x && a[i]+x>=b[i-1]+1)
                {
                    b[i]=b[i-1]+1;
                }
                else if (a[i]-x>=b[i-1]+1)
                {
                    b[i]=a[i]-x;
                }
                else
                {
                    return 0;
                }
            }
        }
        return 1;
    }
    void fen(int l,int r)
    {
        int mid=(l+r)/2;
        if (l<=r)
        {
            if (check(mid))
            {
                ans=mid;
                fen(l,mid-1);
            }
            else
            {
                fen(mid+1,r);
            }
        }
    
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        int cnt=0;
        while(t--)
        {
            cnt++;
            scanf("%d",&n);
            int maxx=0;
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                maxx=max(maxx,a[i]);
            }
            
            fen(0,1000005);
            printf("Case #%d:
    ",cnt);
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

      E题-贪心+二分答案 和C题一样。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<string.h>
     4 #include<stdio.h>
     5 using namespace std;
     6 const int maxx = 2000006;
     7 int ans;
     8 int a[maxx];
     9 int n,m;
    10 bool check(int x)
    11 {
    12     int d=0;
    13     for (int i=1; i<=n; i++)
    14     {
    15         if (a[i]%x==0)
    16         {
    17             d+=a[i]/x;
    18         }
    19         else
    20         {
    21             d+=(a[i]/x+1);
    22         }
    23         if (d>m)return 0;
    24     }
    25     return 1;
    26 }
    27 void fen(int l,int r)
    28 {
    29     //cout<<l<<" "<<r<<endl;
    30     int mid=(l+r)/2;
    31     if (l<=r)
    32     {
    33         if (check(mid))
    34         {
    35             ans=mid;
    36             fen(l,mid-1);
    37         }
    38         else
    39         {
    40             fen(mid+1,r);
    41         }
    42     }
    43 }
    44 int main()
    45 {
    46     while(~scanf("%d%d",&n,&m))
    47     {
    48         if (n==-1 && m==-1)break;
    49         int maxx=0;
    50         for (int i=1; i<=n; i++)
    51         {
    52             scanf("%d",&a[i]);
    53             maxx=max(maxx,a[i]);
    54         }
    55         fen(1,maxx);
    56         printf("%d
    ",ans);
    57     }
    58     return 0;
    59 }
    View Code

      F题-归并排序-课上原题

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<string.h>
     5 using namespace std;
     6 int a[10005];
     7 int n;
     8 int b[10005];
     9 int ans=0;
    10 void gb(int l,int r){
    11   if (l==r)return;
    12   int mid=(l+r)/2;
    13   gb(l,mid);
    14   gb(mid+1,r);
    15   int i=l,j=mid+1,k=l;
    16    while(i<=mid && j<=r)
    17    {
    18        if (a[i]<=a[j])
    19        {
    20            b[k]=a[i];
    21            k++;
    22            i++;
    23        }else
    24        {
    25            b[k]=a[j];
    26            k++;
    27            j++;
    28            ans+=(mid-i+1);
    29        }
    30    }
    31   while(i<=mid)
    32   {
    33       b[k]=a[i];
    34       k++;
    35       i++;
    36   }
    37   while(j<=r)
    38   {
    39       b[k]=a[j];
    40       k++;
    41       j++;
    42   }
    43       for (int i=l;i<=r;i++)
    44         a[i]=b[i];
    45 }
    46 int main(){
    47    while(~scanf("%d",&n)){
    48      ans=0;
    49      for (int i=1;i<=n;i++){
    50         scanf("%d",&a[i]);
    51      }
    52      gb(1,n);
    53      
    54      printf("%d
    ",ans);
    55    }
    56   return 0;
    57 }
    View Code

      G题-物理题,三分,按照物理写出最大距离的公式,三分答案就行

     1 #include<iostream>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<stdio.h>
     5 #include<math.h>
     6 using namespace std;
     7 const double pi = acos(-1);
     8 const double g = 9.8;
     9 int h;
    10 int v;
    11 double ans;
    12 double check(double a)
    13 {
    14    return v*cos(a)*(v*sin(a)/g+sqrt(2*h/g+v*v*sin(a)*sin(a)/(g*g)));
    15 }
    16 void fen(double l,double r)
    17 {
    18     double mid_l,mid_r;
    19     if (r-l>=0.000001){
    20         mid_l=(r-l)/3+l;
    21         mid_r=r-(r-l)/3;
    22         if (check(mid_l)<check(mid_r)){
    23           fen(mid_l,r);
    24           ans=max(ans,check(mid_r));
    25         }
    26         else {
    27           fen(l,mid_r);
    28           ans=max(ans,check(mid_l));
    29       }
    30     }
    31 }
    32 int main(){
    33   int t;
    34   scanf("%d",&t);
    35   while(t--)
    36   {
    37       scanf("%d%d",&h,&v);
    38       ans=0;
    39       double l=0.00;
    40       double r=pi/2;
    41       fen(l,r/2);
    42       printf("%.2f
    ",ans);
    43   }
    44   return 0;
    45 }
    View Code

      H题-最近邻点问题,分治,分两部分考虑,左边和右边,最后求出一个左边和右边的最小值之一,然后取这个最小值来优化判断一个在左边,一个在右边的情况。

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 #include<math.h>
     6 using namespace std;
     7 const int maxx = 1e5+7;
     8 const double INF = 1e20;
     9 struct node{
    10   double x,y;
    11 }p[maxx];
    12 node b[maxx];
    13 double dist(node a,node b)
    14 {
    15     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    16 }
    17 bool cmp1(node a,node b)
    18 {
    19     if (a.x==b.x) return a.y<b.y;
    20     else return a.x<b.x;
    21 }
    22 bool cmp2(node a,node b)
    23 {
    24     return a.y<b.y;
    25 }
    26 double nearest(int left,int right)
    27 {
    28     double d = INF;
    29     if(left == right)return d;
    30     if(left + 1 == right)
    31         return dist(p[left],p[right]);
    32     int mid = (left+right)/2;
    33     double d1 = nearest(left,mid);
    34     double d2 = nearest(mid+1,right);
    35     d = min(d1,d2);
    36     int k = 0;
    37     for(int i = left; i <= right; i++)
    38     {
    39         if(fabs(p[mid].x - p[i].x) <= d)
    40             b[k++] = p[i];
    41     }
    42     sort(b,b+k,cmp2);
    43     for(int i = 0; i <k; i++)
    44     {
    45         for(int j = i+1; j < k && b[j].y - b[i].y < d; j++)
    46         {
    47             d = min(d,dist(b[i],b[j]));
    48         }
    49     }
    50     return d;
    51 }
    52 int main()
    53 {
    54     int n;
    55     while(~scanf("%d",&n) && n)
    56     {
    57       for (int i=0;i<n;i++){
    58          scanf("%lf%lf",&p[i].x,&p[i].y);
    59       }
    60       sort(p,p+n,cmp1);
    61       printf("%.2f
    ",nearest(0,n-1)/2);
    62     }
    63     return 0;
    64 }
    View Code
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    GridView 几个受保护的方法的注释
    完全理解 IDisposable 接口的实现
    C++ 函数调用约定和名称修饰
    硬盘格式转换不影响数据_ convert命令FAT32转NTFS
    Win7系统修复_修复光盘的制作与使用
    双网卡共享上网设置
    Windows?XP系统修复方法
    无线路由器与有线路由器的连接(两个路由器连接)
    无线路由器“无线漫游”
    登录路由器没有弹出登录框_路由器无法登录解决办法
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/9934940.html
Copyright © 2020-2023  润新知