zoukankan      html  css  js  c++  java
  • 2015年百度之星程序设计大赛

    总结 ->过往

    1001:贪心思路,每次尽量选靠后的。

              因为x ,x+1, x+2 如果选了x+2,效果是比x更换的因为我后面的值是在0-k之中,只有尽量k减少的次数更少。

              所以现在假设在x ,我们找y<x+k 找到最大的y;

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include<math.h>
     5 #include <algorithm>
     6 #include <set>
     7 typedef long long ll;
     8 using namespace std;
     9 #define N 1023456
    10 #define inf 0x3f3f3f3
    11 typedef long long ll;
    12 
    13 ll a[N];
    14 int n,m,k;
    15 
    16 int pan(int lxl,int rr,ll x)
    17 {
    18   int flag=0;
    19   int l=lxl,r=rr;
    20 
    21   for (int _=1;_<=50;_++)
    22   {
    23       int mid=(l+r)/2;
    24       if (a[mid]<=x)
    25       {
    26           flag=mid;
    27           l=mid;
    28       }
    29       else r=mid;
    30   }
    31   return flag;
    32 }
    33 
    34 int main()
    35 {
    36     int T;
    37     scanf("%d",&T);
    38     int cas=0;
    39     while (T--)
    40     {
    41 
    42         printf("Case #%d:
    ",++cas);
    43         scanf("%d%d%d",&n,&m,&k);
    44 
    45         ll Max=0;
    46         for (int i=1;i<=n;i++)
    47         scanf("%I64d",&a[i]),Max=max(Max,a[i]);
    48         sort(a+1,a+n+1);
    49         int  idx=pan(1,n,m);
    50         if (!idx)
    51         {
    52             printf("madan!
    ");
    53             continue;
    54         }
    55         ll tmp=a[idx];
    56         while (1)
    57         {
    58             idx=pan(idx+1,n,tmp+k);
    59             if (idx==0)
    60             {
    61                  printf("madan!
    ");
    62                  break;
    63             }
    64             tmp=a[idx];
    65             if (tmp>=Max)
    66             {
    67                  printf("why am I so diao?
    ");
    68                  break;
    69             }
    70             k--;
    71         }
    72     }
    73     return 0;
    74 }
    View Code

    1002:这道题给了直接模拟做,关键点事快速找到 1->k,2->k+1,3->k+2;中是否有连续的数;

             我们可以先求出区间最大值Max,Min;

             首先判断Max-Min==k-1;

             然后用一个数组计入数是否出现两次。用map HASH 注意map HASH预先处理一下,因为在线做毕竟多 一个log

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <cmath>
    #include <iostream>
    #include <map>
    using namespace std;
    #define N 10011
    
    int a[N],b[N];
    int n,m,nn;
    map<int,int>mp;
    
    int dpmin[N][17];
    int dpmax[N][17];
    int cnt[N];
    
    void init()
    {
        for (int i=1;i<=n;i++) dpmin[i][0]=dpmax[i][0]=a[i];
        int mm=log2(n);
        for (int j=1;j<=mm;j++)
        for (int i=1;(i+(1<<j)-1)<=n;i++)
        dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]),
        dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]);
    }
    
    int rmqmax(int l,int r)
    {
        int k=log2(r-l+1);
        return max(dpmax[l][k],dpmax[r-(1<<k)+1][k]);
    }
    int rmqmin(int l,int r)
    {
        int k=log2(r-l+1);
        return min(dpmin[l][k],dpmin[r-(1<<k)+1][k]);
    }
    int f[N];
    
    int main()
    {
           scanf("%d%d",&n,&m);
           mp.clear();
           puts("Case #1:");
           for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
           sort(b+1,b+n+1);
           int  nn=unique(b+1,b+n+1)-b-1;
           for (int i=1;i<=nn;i++) mp[b[i]]=i;
           for (int i=1;i<=n;i++) f[i]=mp[a[i]];
           init();
           while (m--)
           {
               int k;
               scanf("%d",&k);
               if (k>n)
               {
                   printf("0
    ");
                   continue;
               }
               memset(cnt,0,sizeof(cnt));
               int ans=0;
               int chong=0;
               for (int i=1;i<=k;i++)
               {
                   int idx =f[i];
                   cnt[idx]++;
                   if (cnt[idx]==2) chong++;
    
               }
               int _max=rmqmax (1,k);
               int _min=rmqmin (1,k);
    
               if (!chong&&_max-_min==k-1) ans++;
    
               for (int i=k+1;i<=n;i++)
               {
                   int x =f[i-k];
                   int y =f[i];
                       cnt[x]--;
                       if (cnt[x]==1) chong--;
    
                       cnt[y]++;
                       if (cnt[y]==2) chong++;
    
                   _max=rmqmax(i-k+1,i);
                   _min=rmqmin(i-k+1,i);
                   if (!chong&&_max-_min==k-1) ans++;
               }
               printf("%d
    ",ans);
           }
       return 0;
    }

    1003:水

    二分答案,判断是否可行

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include<math.h>
     5 #include <algorithm>
     6 typedef long long ll;
     7 using namespace std;
     8 #define N 1023456
     9 #define inf 0x3f3f3f3
    10 
    11 int a[N],b[N];
    12 int n;
    13 
    14 int pan(int x)
    15 {
    16     for (int i=1;i<=n;i++) b[i]=a[i];
    17     b[1]=b[1]-x;
    18 
    19     for (int i=2;i<=n;i++)
    20     {
    21         int tmpx=b[i]-x;
    22         int tmpy=b[i]+x;
    23         if (b[i-1]>=tmpy) return 0;
    24         b[i]=max(tmpx,b[i-1]+1);
    25     }
    26     return  1;
    27 }
    28 
    29 int main()
    30 {
    31     int T;
    32     scanf("%d",&T);
    33     int cas=0;
    34     while (T--)
    35     {
    36         printf("Case #%d:
    ",++cas);
    37         scanf("%d",&n);
    38         for (int i=1;i<=n;i++)
    39         scanf("%d",&a[i]);
    40 
    41         int l=0,r=1234567;
    42         for (int _=1;_<=60;_++)
    43         {
    44             int mid=(l+r)/2;
    45             if (pan(mid)) r=mid;
    46             else l=mid;
    47         }
    48         printf("%d
    ",r);
    49     }
    50     return 0;
    51 }
    View Code

    1004:

    很多平衡树,可是我并不会写treap,splay;

    于是离线处理,BIT处理前缀和

    具体做法:一个数记录当前管道里面有多少个数,用来求中位数;

                离散所有出现的数,相对应的记录下标;

                对 in 的数 树状数组更新 1,

                对out 的数更新 -1;

                query的数比较麻烦,我们可以二分求出最小的x sum(x)==此刻中位数的答案{说的乱}

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include<cmath>
      5 #include <algorithm>
      6 
      7 
      8 typedef long long ll;
      9 using namespace std;
     10 #define N 102345
     11 #define inf 0x3f3f3f3
     12 typedef long long ll;
     13 int type[N],a[N],b[N],f[N];
     14 
     15 int n,num;
     16 
     17 
     18 int lowbit(int x)
     19 {
     20     return x&(-x);
     21 }
     22 
     23 int sum(int x)
     24 {
     25     int s=0;
     26     while (x)
     27     {
     28         s+=f[x];
     29         x-=lowbit(x);
     30     }
     31     return s;
     32 }
     33 
     34 void update(int x,int val)
     35 {
     36     while (x<=num)
     37     {
     38         f[x]+=val;
     39         x+=lowbit(x);
     40     }
     41 }
     42 
     43 
     44 int pan(int l,int r,int tans)
     45 {
     46     for (int _=1;_<=50;_++)
     47     {
     48         int mid=(l+r)>>1;
     49         if (sum(mid)>=tans) r=mid;
     50         else l=mid;
     51     }
     52     return r;
     53 }
     54 
     55 int main()
     56 {
     57 
     58     int cas=0;
     59     while (scanf("%d",&n)!=EOF)
     60     {
     61         printf("Case #%d:
    ",++cas);
     62         memset(f,0,sizeof(f));
     63         char s[10];
     64         num=0;
     65         
     66         for (int i=1;i<=n;i++)
     67         {
     68             int x;
     69             scanf("%s",s);
     70             if (s[0]=='i')
     71             {
     72                 scanf("%d",&x);
     73                 type[i]=1;
     74                 a[++num]=x;
     75 
     76             }
     77             else if (s[0]=='o')
     78             type[i]=3;
     79             else type[i]=2;
     80         }
     81         
     82         for (int i=1;i<=num;i++) b[i]=a[i];
     83         sort(b+1,b+num+1);
     84 
     85         int p=1;
     86         int num1=1;
     87         int fuck=0;
     88 
     89         for (int i=1;i<=n;i++)
     90         {
     91             if (type[i]==1)
     92             {
     93                 int idx=lower_bound(b+1,b+num+1,a[num1])-b;
     94                 update(idx,1);
     95                 num1++;
     96                 fuck++;
     97             }
     98             else if (type[i]==2)
     99             {
    100                 int tmp=floor(fuck/2)+1;
    101                 
    102                 int  ans=b[pan(1,num,tmp)];
    103                 printf("%d
    ",ans);
    104             }
    105             else
    106             {
    107               fuck--;
    108               int idx=lower_bound(b+1,b+num+1,a[p])-b;
    109               update(idx,-1);
    110               p++;
    111             }
    112         }
    113     }
    114     return 0;
    115 }
    View Code        

     请结合 代码

     这题还有2个set的 写法,因为是求得中位数。

    1005:写不出来

    10056:模板,做法是 一个矩形覆盖所有出现的点。求次矩形最小面积

                 凸包求,加旋转卡壳(具体百度其他)

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <algorithm>
      5 #include <cmath>
      6 
      7 #define MAXN 51000
      8 #define EPS 1e-10
      9 
     10 using namespace std;
     11 
     12 int n;
     13 double minsqr; //minsqr=最小矩形面积
     14 
     15 int dcmp(double x)
     16 {
     17     if(fabs(x)<EPS) return 0;
     18     if(x>-EPS) return 1;
     19     return -1;
     20 }
     21 
     22 struct Point
     23 {
     24     double x,y;
     25     Point(){}
     26     Point(double _x,double _y):x(_x),y(_y){}
     27     void read()
     28     {
     29         scanf("%lf%lf",&x,&y);
     30     }
     31 }points[MAXN],stack[MAXN<<1],ans[10]; //ans保存最小覆盖矩形的四个顶点
     32 
     33 Point operator-(Point a,Point b)
     34 {
     35     return Point(a.x-b.x,a.y-b.y);
     36 }
     37 
     38 Point operator*(Point a,double b)
     39 {
     40     return Point(a.x*b,a.y*b);
     41 }
     42 
     43 Point operator+(Point a,Point b)
     44 {
     45     return Point(a.x+b.x,a.y+b.y);
     46 }
     47 
     48 double cross(Point a,Point b,Point c) //a->b 叉积 a->c
     49 {
     50     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
     51 }
     52 
     53 double dot(Point a,Point b,Point c) //a->b 点积 b->c
     54 {
     55     return (b.x-a.x)*(c.x-b.x)+(b.y-a.y)*(c.y-b.y);
     56 }
     57 
     58 double dist(Point a,Point b)
     59 {
     60     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     61 }
     62 
     63 int top=0;
     64 
     65 bool cmp(Point a,Point b)
     66 {
     67     if(!dcmp(a.x-b.x)) return a.y<b.y;
     68     return a.x<b.x;
     69 }
     70 
     71 bool operator<(Point a,Point b)
     72 {
     73     if(!dcmp(a.y-b.y)) return a.x<b.x;
     74     return a.y<b.y;
     75 }
     76 
     77 void Graham()
     78 {
     79     sort(points+1,points+n+1,cmp);
     80     for(int i=1;i<=n;i++) //下凸壳
     81     {
     82         while(top>=2&&dcmp(cross(stack[top-1],stack[top],points[i])<=0)) top--;
     83         stack[++top]=points[i];
     84     }
     85     int tmp=top;
     86     for(int i=n-1;i>=1;i--) //上凸壳
     87     {
     88         while(top>=tmp+1&&dcmp(cross(stack[top-1],stack[top],points[i])<=0)) top--;
     89         stack[++top]=points[i];
     90     }
     91     top--; //栈顶显然是points[1],重复了一次,将重复的丢掉
     92 }
     93 
     94 void rotcalip() //旋转卡壳
     95 {
     96     int left=1,right=1,up=1; //左、右、上三个点
     97     for(int i=1;i<=top;i++)
     98     {
     99         while(dcmp(cross(stack[up+1],stack[i],stack[i+1])-cross(stack[up],stack[i],stack[i+1]))>=0) up=up%top+1;
    100         while(dcmp(dot(stack[right+1],stack[i+1],stack[i])-dot(stack[right],stack[i+1],stack[i]))>=0) right=right%top+1;
    101         if(i==1) left=right;
    102         while(dcmp(dot(stack[left+1],stack[i],stack[i+1])-dot(stack[left],stack[i],stack[i+1]))>=0) left=left%top+1;
    103         double L=dist(stack[i],stack[i+1]); //L=点i到i+1的距离
    104         double H=cross(stack[i+1],stack[up],stack[i])/L; //H是矩形的高
    105         double bottom=(fabs(dot(stack[i],stack[i+1],stack[left])/L)+fabs(dot(stack[i],stack[i+1],stack[right])/L));
    106         double nowsqr=bottom*H;
    107         if(nowsqr<minsqr) //这个解比当前答案更优
    108         {
    109             minsqr=nowsqr;
    110             ans[0]=stack[i]+(stack[i+1]-stack[i])*((fabs(dot(stack[i],stack[i+1],stack[right]))/L+L)/L);
    111             ans[1]=ans[0]+(stack[right]-ans[0])*(H/dist(stack[right],ans[0]));
    112             ans[2]=ans[1]+(stack[up]-ans[1])*(bottom/dist(stack[up],ans[1]));
    113             ans[3]=ans[2]+(stack[left]-ans[2])*(H/dist(stack[left],ans[2]));
    114         }
    115     }
    116 }
    117 void init()
    118 {
    119     top=0;
    120 }
    121 
    122 int main()
    123 {
    124      int cas;
    125      scanf("%d",&cas);
    126      for (int _=1;_<=cas;_++)
    127      {
    128          init();
    129     printf("Case #%d:
    ",_);
    130     minsqr=1e12;
    131     scanf("%d",&n);
    132     for(int i=1;i<=n*4;i++)
    133     points[i].read();
    134     n=n*4;
    135     Graham();
    136     rotcalip();
    137     int ans=round(minsqr);
    138     printf("%d
    ",ans);
    139      }
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    视图
    使用navicat for sqlserver 把excel中的数据导入到sqlserver数据库
    sql去重
    SQLserver连接本地服务器
    html中去掉文本框(input type="text")的边框或只显示下边框
    用户控件与页面间相互给各自的控件赋值
    easyui datagrid 去掉 全选checkbox
    ZebraDatepicker中文显示
    实现在点击asp:button按钮后,不刷新当前页面
    (转)ASP.NET(C#)FileUpload实现上传限定类型和大小的文件到服务器
  • 原文地址:https://www.cnblogs.com/forgot93/p/4541576.html
Copyright © 2011-2022 走看看