zoukankan      html  css  js  c++  java
  • 8月10号的练习:ZOJ 3203&&POJ 3974&&HDU 1394&&HDU 3400&&HDU 2152

                                            Light Bulb  ZOJ 3203

    又是一道数学题:(三分法)

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 using namespace std;
     5 int main()
     6 {
     7     double H,h,D,l,r,mid,mmid;
     8     int n;
     9     scanf("%d",&n);
    10     while(n--)
    11     {
    12         scanf("%lf%lf%lf",&H,&h,&D);
    13         l=(H-h)*D/H;
    14         r=D;mid=0;mmid=0;
    15         while(r-l>1e-9)
    16         {
    17             mid=(l+r)/2;
    18             mmid=(mid+r)/2;
    19             if((mid+(H-h)*D/mid)>(mmid+(H-h)*D/mmid))
    20                 l=mid;
    21             else if((mid+(H-h)*D/mid)<(mmid+(H-h)*D/mmid))
    22                 r=mmid;
    23             else
    24                 break;
    25         }
    26         printf("%.3lf
    ",D+H-(l+(H-h)*D/l));
    27     }
    28     return 0;
    29 }

    貌似不能二分角度!没有图不好说,具体参见:http://blog.csdn.net/freezhanacmore/article/details/9887115(里面有数学解法)

                              Palindrome POJ 3974

    一道求最长回文子串:(必须是连续的)

    就是用什么Manacher算法:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<string.h>
     5 #include<string>
     6 using namespace std;
     7 char a[1000005],b[2000005];
     8 int d[2000005];
     9 int main()
    10 {
    11     int n,i,mia,ip,max1,d1=0;
    12     while(scanf("%s",a)!=EOF)
    13     {
    14         if(a[0]=='E')
    15             break;
    16         n=strlen(a);
    17         b[0]='@';
    18         b[1]='#';
    19         for(i=0;i<n;i++)
    20         {
    21             b[i*2+2]=a[i];
    22             b[i*2+3]='#';
    23         }
    24         b[2*n+2]='';
    25         n=2*n+2;
    26         mia=0;
    27         ip=0;
    28         max1=1;
    29         for(i=0;i<n;i++)
    30         {
    31             if(mia>i)
    32                 d[i]=min(d[2*ip-i],mia-i);
    33             else
    34                 d[i]=1;
    35             for(;b[i-d[i]]==b[i+d[i]];d[i]++)
    36             if(i+d[i]>mia)
    37             {
    38                 mia=i+d[i];
    39                 ip=i;
    40             }
    41             max1=max(max1,d[i]);
    42         }
    43         printf("Case %d: %d
    ",++d1,max1-1);
    44     }
    45     return 0;
    46 }

    该算法的基本思路:

    先是把原字符串扩大两倍:每隔一个插上‘#’,听说可以避免奇偶性的讨论。

    之后还有一个剪枝问题:具体参见:http://www.2cto.com/kf/201210/164253.html

                               Minimum Inversion Number  HDU 1394

    一道线段树的问题,可以暴力也可树状数组:(由于精力有限,只用了线段数)

    还是逆序数的问题:(这道不用离散化)

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 using namespace std;
     5 struct line
     6 {
     7     int left;
     8     int right;
     9     int ma;
    10 }a[5005];
    11 void build(int left,int right,int root)
    12 {
    13     a[root].left=left;
    14     a[root].right=right;
    15     a[root].ma=0;
    16     if(left==right)
    17         return ;
    18     build(left,(left+right)/2,2*root);
    19     build((left+right)/2+1,right,2*root+1);
    20 }
    21 void insert1(int x,int root)
    22 {
    23     if(x<a[root].left||x>a[root].right)
    24         return ;
    25     if(x==a[root].left&&x==a[root].right)
    26     {
    27             a[root].ma++;return ;
    28     }
    29     if(x>=a[root].left&&x<=a[root].right)
    30         a[root].ma++;
    31     insert1(x,2*root);
    32     insert1(x,2*root+1);
    33 }
    34 int find1(int left,int right,int root)
    35 {
    36     if(a[root].left>=left&&a[root].right<=right)
    37         return a[root].ma;
    38     if(a[root].left>right||left>a[root].right)
    39         return 0;
    40     return (find1(left,right,2*root)+find1(left,right,2*root+1));
    41 }
    42 int main()
    43 {
    44     int sum,min1,n,i;
    45     int a1[5005];
    46     while(scanf("%d",&n)!=EOF)
    47     {
    48         build(1,n,1);
    49         sum=0;
    50         for(i=1;i<=n;i++)
    51         {
    52             scanf("%d",&a1[i]);
    53             a1[i]++;
    54             insert1(a1[i],1);
    55             sum+=find1(a1[i]+1,n,1);//需要边更新,边求值
    56         }
    57         min1=sum;
    58         for(i=1;i<=n-1;i++)
    59         {
    60             sum-=a1[i]-1;
    61             sum+=n-a1[i];//题目求的是最小值,每次把第一个数移到最后的最小值(逆序数的变化很明显)
    62             if(sum<min1)
    63                 min1=sum;
    64         }
    65         printf("%d
    ",min1);
    66     }
    67     return 0;
    68 }

    要得出答案主要是利用了一个结论:如果是0到n的排列,那么如果把第一个数放到最后,对于这个数列,逆序数是减少y[i],而增加n-1-y[i]的。(可以这样想,因为是第一个数,所有的数都在它后面,那么在当前位置pos比它大的数也在它后面,那么第一个数调到后面之后,在pos不成立的逆序数就成立了,所以多了n-y[i]-1,但是也少了在pos成立的逆序数,即y[i]个)

                                                     Line belt HDU 3400

    三分题:(要进行两次三分求解)

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<math.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<string.h>
     7 using namespace std;
     8 struct point
     9 {
    10     double x,y;
    11 };
    12 double dis(point a,point b)
    13 {
    14     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    15 }
    16 double p,q,r;
    17 double find2(point a,point c,point d)
    18 {
    19     point left,right;
    20     point mid,midmid;
    21     double t1,t2;
    22     left=c;
    23     right=d;
    24     do
    25     {
    26         mid.x=(left.x+right.x)/2;
    27         mid.y=(left.y+right.y)/2;
    28         midmid.x=(mid.x+right.x)/2;
    29         midmid.y=(mid.y+right.y)/2;
    30         t1=dis(a,mid)/r+dis(mid,d)/q;
    31         t2=dis(a,midmid)/r+dis(midmid,d)/q;
    32         if(t1>t2)
    33            left=mid;
    34         else
    35             right=midmid;
    36     }while(dis(left,right)>=1e-9);
    37     return t1;
    38 }
    39 double find(point a,point b,point c,point d)
    40 {
    41     point left,right;
    42     point mid,midmid;
    43     double t1,t2;
    44     left=a;
    45     right=b;
    46     do
    47     {
    48         mid.x=(left.x+right.x)/2;
    49         mid.y=(left.y+right.y)/2;
    50         midmid.x=(mid.x+right.x)/2;
    51         midmid.y=(mid.y+right.y)/2;
    52         t1=dis(a,mid)/p+find2(mid,c,d);
    53         t2=dis(a,midmid)/p+find2(midmid,c,d);
    54         if(t1>t2)
    55         left=mid;
    56         else
    57             right=midmid;
    58     }while(dis(left,right)>=1e-9);
    59     return t1;
    60 }
    61 int main()
    62 {
    63     int T;
    64     point a,b,c,d;
    65     scanf("%d",&T);
    66     while(T--)
    67     {
    68         scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
    69         scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
    70         scanf("%lf%lf%lf",&p,&q,&r);
    71         printf("%.2lf
    ",find(a,b,c,d));
    72     }
    73     return 0;
    74 }

    之后是到母函数:可以说是模板题了。

                                               Fruit  HDU 2152

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<string.h>
     5 using namespace std;
     6 int main()
     7 {
     8     int a[105],b[105];
     9     int c1[10005],c2[10005];
    10     int n,m,i,j,k;
    11     while(scanf("%d%d",&n,&m)!=EOF)
    12     {
    13         for(i=1;i<=n;i++)
    14             scanf("%d%d",&a[i],&b[i]);
    15         memset(c1,0,sizeof(c1));
    16         memset(c2,0,sizeof(c2));
    17         c1[0]=1;
    18         for(i=1;i<=n;i++)
    19         {
    20             for(j=0;j<=m;j++)
    21                 for(k=a[i];k<=m&&k<=b[i];k++)
    22                 c2[k+j]+=c1[j];
    23             for(j=0;j<=m;j++)
    24             {
    25                 c1[j]=c2[j];
    26                 c2[j]=0;
    27             }
    28         }
    29         printf("%d
    ",c1[m]);
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    [hdu6271]Master of Connected Component
    [hdu5468]Puzzled Elena
    [hdu4582]DFS spanning tree
    [poj2054]Color a Tree
    [luogu4107]兔子和樱花
    整除的尾数[HDU2099]
    胜利大逃亡[HDU1253]
    Bitset[HDU2051]
    折线分割平面[HDU2050]
    不容易系列之(4)——考新郎[HDU2049]
  • 原文地址:https://www.cnblogs.com/tt123/p/3252141.html
Copyright © 2011-2022 走看看