• 8月10号小练


    网站:csust训练3

    A 三分的题目,给出灯高,人高,以及和墙的距离,求最长的影子长度。   Light Bulb     ZOJ 3203    

    本来我是三分角度,角度[0,atan(H/D)],测试数据都是对的,但是WA了,我到现在还是不知道为什么........

    后来是三分投在墙上的影子长度,[0,h],投在墙上的影子最多是h。

    代码:     0MS

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

    这道题还有个数学方法,直接求峰值,详情见:http://blog.csdn.net/freezhanacmore/article/details/9887115 (表示膜拜,用数学方法的都膜拜)

    B   求最长回文子串的长度,如果暴力0(n^2)果断超时,要用Manacher算法。

    优化原因见:  http://www.2cto.com/kf/201210/164253.html

    代码: 360 ms/15000ms     10936kb/65536kb     这道题的时间限制真长......从没做过15s的题Orz

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio> 
     4 using namespace std;
     5 #define N 1000008
     6 char str[N], str1[N<<1];
     7 int p[N<<1];
     8 int maxx;
     9 void Manacher()
    10 {
    11     int i, j, mx, id;
    12     memset(str1, '#', sizeof(str1));
    13     memset(p, 0, sizeof(p));    
    14     for(i=0; str[i]!=''; i++)
    15         str1[(i+1)<<1]=str[i];    //把字符插入到#####中
    16     str1[(i+1)<<1]='';   
    17     mx=0;
    18     maxx=0;
    19     for(i=1; str1[i]!=''; i++)
    20     {
    21        if( mx>i ) 
    22            p[i]=min(mx-i, p[id*2-i]);    //见:http://www.cnblogs.com/lv-2012/archive/2012/11/15/2772268.html    PS:没有这一步会超时
    23         else 
    24             p[i]=1; 
    25         while( str1[i-p[i]]==str1[i+p[i]] )    //拓展半径
    26             p[i]++;        
    27         if( i+p[i]>mx )//mx代表当前回文串扩展的最大距离 
    28         {
    29             mx=i+p[i];  
    30             id=i;
    31         }         
    32         if( p[i]-1>maxx )    
    33             maxx=p[i]-1;    //更新最长长度
    34     }    
    35 }
    36 int main()
    37 {
    38     int Case=0;
    39     while( scanf("%s", str) && strcmp(str, "END")!=0 )   //str!=END
    40     {
    41         maxx=0;
    42         Manacher();
    43         printf("Case %d: %d
    ",++Case,maxx); 
    44     }
    45 } 

    C    Minimum Inversion Number   HDU 1394   大意是给n个数,分别是0~n-1,前面的数比后面的数大的数对有多少个,算好之后把第一个数移到最后,又算.......最后求最小的数对是多少个。此题用线段树做,但是我还没看线段树,过一阵再补上,先讲下不用线段树的做法。

    代码  :   265ms

     1 #include <stdio.h>
     2 #include <iostream>
     3 using namespcae std;
     4 int main()
     5 {
     6     int n,i,j,sum,minn,sum1
     7     while(~scanf("%d",&n))
     8     {
     9         sum=0;
    10         for(i=0;i<n;i++)
    11             scanf("%d",&a[i]);
    12         for(i=0;i<n-1;i++)
    13             for(j=i+1;j<n;j++)
    14                 if(a[i]>a[j])
    15                     sum++;   //求出初数列的个数
    16         minn=sum;   //初始化最小值
    17         for(i=1;i<n;i++)
    18         {
    19             sum1=sum+n-1-2*a[i];     //sum1=sum(上一个数列的值)+(n-1-a[i])(移到后面的那个数和最大数的差值)-a[i](比a[i]小的数的个数)
    20             if(minn>sum1)
    21                 minn=sum1;    //更新最小值
    22             sum=sum1;   //更新上一个数列的值
    23         }
    24         printf("%d
    ",minn);
    25     }
    26     return 0;
    27 }

    D     Line belt   HDU 3400   三分叠三分

    代码:     0MS ,注意不能用while,用do....while,因为至少要执行一次,算AB,CD 间的距离

     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)//三分CD
    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;    //ids(a,mid)是求AB,CD间的距离
    32         if(t1>t2)
    33            left=mid;
    34         else
    35             right=midmid;
    36     }while(dis(left,right)>1e-5);   
    37     return t2;
    38 }
    39 double find(point a,point b,point c,point d)   //三分AB
    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-5);
    59     return t2;
    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 }

    E   超级简单,母函数解决 Fruit   HDU 2152

    代码:    0ms

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 int a[105],b[105];
     6 int c1[10005],c2[10005];
     7 int main()
     8 {
     9     int n,m,i,j,k;
    10     while(~scanf("%d%d",&n,&m))
    11     {
    12         for(i=1;i<=n;i++)
    13             scanf("%d%d",&a[i],&b[i]);
    14         memset(c1,0,sizeof(c1));
    15         memset(c2,0,sizeof(c2));
    16         c1[0]=1;
    17         for(i=1;i<=n;i++)
    18         {
    19             for(j=0;j<=m;j++)
    20                 for(k=a[i];j+k<=m&&k<=b[i];k++)
    21                 c2[j+k]+=c1[j];
    22             for(j=0;j<=m;j++)
    23                 c1[j]=c2[j];
    24             memset(c2,0,sizeof(c2));
    25         }
    26         printf("%d
    ",c1[m]);
    27     }
    28     return 0;
    29 }
  • 相关阅读:
    linux性能测试(转)
    mysql基本操作(数据库,表,字段,记录)
    mysql数据库的简介(安装和卸载)
    mysql数据库
    枚举法
    python数据结构与算法简介
    自学心得
    python 进程线程阅读摘抄
    python并发编程多线程基础1
    python队列
  • 原文地址:https://www.cnblogs.com/riddle/p/3251109.html
Copyright © 2020-2023  润新知