20140425 虚拟赛 中南大学第八届大学生程序设计竞赛

A - 身体质量指数
Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

身体质量指数(BMI是用一个人的体重(单位:kg)除以身高(单位:m)的平方得出的数值(单位:kg/m2,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。
BMI = 体重(kg) / (身高(m))2
比如,如果一个人的体重和身高分别为70kg1.75m,那么他的BMI70 / 1.752 ≈ 22.86kg/m2
对于中国人来讲,如果一个人的BMI小于18.5,说明他体重过轻;如果BMI大于或等于23,说明他体重过重;否则,说明他的体重是正常的。
给出一个中国人的体重和身高,计算他的BMI并指出他的体重是否正常。

Input

输入的第一行包含一个整数T (1   T    200),表示一共有T组测试数据。
每组测试数据占一行,包含两个带有两位小数的浮点数MH (40.00   M   150.00, 1.3  H   2.30),表示这个中国人的体重为M(单位:kg),身高为H(单位:m)。

Output

对于每组测试数据,输出一个字符串表示这个人的体重是否正常。如果这个人的体重过重,输出“Overweight”(不包含引号);如果这个人体重过轻,输出“Underweight”(不包含引号);否则,输出“Normal”(不包含引号)。

Sample Input

5
70.00 1.75
73.99 2.00
74.00 2.00
92.00 2.00
91.99 2.00

Sample Output

Normal
Underweight
Normal
Overweight
Normal

 

#include<stdio.h>

//的BMI小于18.5,说明他体重过轻;如果BMI大于或等于23,说明他体重过重
int main()
{
    double a,b,h;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf",&a,&h);
        double b = a/(h*h);
        if(b < 18.50)
            printf("Underweight\n");
        else
            if(b >= 23.0)
                printf("Overweight\n");
                else
                printf("Normal\n");
    }
    return 0;
}
View Code

 

B - 最短距离
Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

两个点AB均在做匀速直线运动。给出t = 0时刻AB的坐标,以及AB的速度,计算t   0时两个点的距离的最小值。

Input

输入的第一行包含一个整数T (1   T    200),表示一共有T组测试数据。
对于每组测试数据,第一行包含4个整数xAyAvAxvAy (-103    xAyAvAxvAy   103),表示t = 0时刻A的坐标为(xAyA),A的速度在x轴方向上的分量为vAx,在y轴上的分量为vAy。第二行包含四个整数xByBvBxvBy (-103    xByBvBxvBy   103),以相同的方式给出了B的各项属性。

Output

对于每组测试数据,输出t   0时两个点距离的最小值,保留8位小数。

Sample Input

6
0 0 0 0
0 1 0 1
0 0 -1 1
0 0 1 -1
0 1 1 0
2 0 0 1
0 1 1 0
2 0 1 0
0 0 -1 1
1 1 1 -1
997 997 -1000 -1000
-1000 -1000 1000 1000

Sample Output

1.00000000
0.00000000
0.70710678
2.23606798
1.41421356
0.00000000

题目大意:转化为抛物线求最小值(y=at^2+bt+c),需要注意的是a可能等于0(0不能作除数)。
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 struct Point
 8 {
 9     double x,y;
10     Point(double x=0,double y=0):x(x),y(y) {}
11 };
12 
13 typedef Point Vector;
14 const double eps=1e-9;
15 
16 int main()
17 {
18     //freopen("a.txt","r",stdin);
19     int T;
20     double ans,a,b,c;
21     Point A,B,C;
22     Vector v1,v2;
23     scanf("%d",&T);
24     while(T--)
25     {
26         scanf("%lf %lf %lf %lf",&A.x,&A.y,&v1.x,&v1.y);
27         scanf("%lf %lf %lf %lf",&B.x,&B.y,&v2.x,&v2.y);
28         a=(v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y);
29         b=2*(v1.x-v2.x)*(A.x-B.x)+2*(v1.y-v2.y)*(A.y-B.y);
30         c=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
31         if(fabs(a-0)<eps)
32         {
33             printf("%.8lf\n",sqrt(c));
34             continue;
35         }
36         ans=-b/2/a;
37         if(0-ans>eps) printf("%.8lf\n",sqrt(c));
38         else if(fabs(0-ans)<eps) printf("%.8lf\n",sqrt(c));
39         else if(ans-0>eps) printf("%.8lf\n",sqrt((4*a*c-b*b)/4/a));
40     }
41     return 0;
42 }
View Code


C - 种植树苗
Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

如下图所示,我们在门前一条笔直的道路上栽了N棵树苗。 
但是,最近我们发现,如果两棵树苗的距离小于一个常数D,这两棵树苗的发育都会受到阻碍。因此我们决定移除一些树苗,从而使任意两棵树苗的距离都不小于D,并且我们希望留下的树苗越多越好。

Input

输入的第一行包含一个整数T (T > 0),表示一共有T组测试数据。
对于每组测试数据,第一行包含两个整数ND (1 ≤ N ≤ 105, 1 ≤ D ≤ 109)。第二行包含N个整数a1a2, ..., aN (0 < a1 < a2 < ... < aN < 109),其中ai (1 ≤ i ≤ N)表示第i棵树苗的位置。

Output

对于每组测试数据,输出我们最多可以留下多少棵树苗,并且任意两棵树苗的距离都不小于D

Sample Input

5
1 3
7
2 1
3 4
2 2
3 4
7 2
1 2 3 5 6 8 9
7 4
1 2 3 5 6 8 9

Sample Output

1
2
1
4
3

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define maxn 100009
 4 int vis[maxn];
 5 int dis[maxn];
 6 int main()
 7 {
 8     int n,i,d,t;
 9     scanf("%d",&t);
10     while(t--)
11     {
12         scanf("%d%d",&n,&d);
13         for(i=0;i<n;i++)
14             scanf("%d",&dis[i]);
15         memset(vis,0,sizeof(vis));
16         int temp = dis[0];
17         for(i=1;i<n;i++)
18         {
19             if(dis[i] - temp < d)
20                 vis[i] = 1;
21             else
22                 temp = dis[i];
23         }
24         int sum = 0;
25         for(i=0;i<n;i++)
26             if(!vis[i]) sum ++;
27             printf("%d\n",sum);
28     }
29     return 0;
30 }
View Code

 

D - 集合的并
Time Limit:3000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

给出两个由整数组成的集合AB,计算A    B中包含多少个整数。

Input

输入的第一行包含一个整数T (T > 0),表示一共有T组测试数据。
对于每组测试数据,第一行包含一个整数n (1   n   105)。第二行包含2n个整数a1b1a2b2, ..., anbn (0 < a1    b1 < a2    b2 < ... < an   bn < 109),表示A = [a1b1 [a2b2 ...  [anbn]。第三行包含一个整数m (1   m   105)。第四行包含2m个整数c1d1c2d2, ..., cmdm (0 < c1   d1 < c2    d2 < ... < cm    dm < 109),表示B = [c1d1 [c2d2 ...  [cmdm]。
这里[xy]表示由xy之间(包含xy)所有整数组成的集合。

Output

对于每组测试数据,输出A    B中包含多少个整数

Sample Input

3
1
7 7
1
3 3
2
1 2 3 4
1
2 3
2
1 2 4 6
3
1 3 6 7 9 10

Sample Output

2
4
9

Hint

 

对样例1的解释:A = {7},B = {3},A    B = {3, 7}。

对样例2的解释:A = {1, 2, 3, 4},B = {2, 3},A    B = {1, 2, 3, 4}。

对样例3的解释:A = {1, 2, 4, 5, 6},B = {1, 2, 3, 6, 7, 9, 10},A    B = {1, 2, 3, 4, 5, 6, 7, 9, 10}。

 

 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=200005;
int n,m;

struct point
{
    int x,y;
}f[maxn];

bool mycomp(const point &a,const point &b)
{
    if(a.x!=b.x) return a.x<b.x;
    else return a.y>b.y;
}

void solve() 
{
    int i,ans = 0;
    int start=0;
    for(i=0;i<n+m;i++)
    {
        if(f[i].x>start) start=f[i].x;
        if (f[i].y>=start)
        {
            ans+=f[i].y-start+1;
            start = f[i].y+1;            
        }
    }
    printf("%d\n",ans);
}

int main()
{
    int t,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++) scanf("%d %d",&f[i].x,&f[i].y);
        scanf("%d",&m);
        for(i=n;i<m+n;i++) scanf("%d %d",&f[i].x,&f[i].y);
        sort(f,f+n+m,mycomp);
        solve();
    }
    return 0;
}
View Code

 

E - 整数转换
Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

我们可以通过对一个整数A进行加1操作或者乘2操作使其转换为另一个整数B
给出两个整数XY,计算至少需要多少步才能将X转换为Y.

Input

输入的第一行包含一个整数T (1   T   500),表示一共有T组测试数据。
每组测试数据占一行,包含两个整数XY (1   X  ≤ Y ≤ 1018)。

Output

对于每组测试数据,输出至少需要多少步才能将X转换为Y

Sample Input

3
1 1
3 10
2 11

Sample Output

0
3
4

Hint

 

对样例2的解释:只需3步即可将3转换为10:3  ->  4  ->  5  ->  10

对样例3的解释:只需4步即可将2转换为11:2  ->  4  ->  5  ->  10  ->  11

 

#include<iostream>
#include<cstdio>
using namespace std;

typedef long long LL;
LL a,b;

void solve()
{
    LL ans=0;
    scanf("%lld %lld",&a,&b);
    while(a<b)
    {
        if(b/2<a) ans+=b-a,b=a;
        else if(b/2>=a)
        {
            if(b%2) ans+=2,b=b/2;
            else ans++,b/=2;
        }
    }
    printf("%lld\n",ans);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
        solve();
    return 0;
}
View Code

 

G - Line and Circles
Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

There are several circles in the plane, and they have the same radius. If there is a straight line can cross all the circles?
We say a straight line crosses a circle if and only if they have at least one point of intersection.

Input

The first line contains one integer T (T > 0), means there are T test cases.
For each test case, the first line contains two integers NR (1   N   1051    R  104), giving the number of circles and the radius of these circles. Then follow N lines with two integers xy (0  xy < 109), giving the coordinate of the center of each circle.

Output

For each test case, output “Yes” (without quotation marks) in one line if there exists a straight line can cross all the circles. Otherwise output “No” (without quotation marks) instead.

Sample Input

3
3 1
0 3
3 1
6 3
3 1
0 3
3 0
6 3
4 2
1 0
1 0
5 5
3 3

Sample Output

Yes
No
Yes

 

 题目大意:给n个圆(n>=1),求是否有一条直线穿过所有的圆。
解题思路:对n圆心求凸包,若在某一个方向上两最远点的距离小于等于圆的直径,则存在这么一条直线。需要注意的是n=1要特殊处理。
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<vector>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 double r;
  9 const double eps=1e-8;
 10 
 11 struct Point {
 12     double x, y;
 13     Point(double x=0, double y=0):x(x),y(y) { }
 14 };
 15 
 16 typedef Point Vector;
 17 
 18 Vector operator - (const Point& A, const Point& B) {
 19     return Vector(A.x-B.x, A.y-B.y);
 20 }
 21 
 22 double Cross(const Vector& A, const Vector& B) {
 23     return A.x*B.y - A.y*B.x;
 24 }
 25 
 26 double Dot(const Vector& A, const Vector& B) {
 27     return A.x*B.x + A.y*B.y;
 28 }
 29 
 30 double Length(const Point& A) {
 31     return sqrt(Dot(A,A));
 32 }
 33 
 34 bool operator < (const Point& p1, const Point& p2) {
 35     return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
 36 }
 37 
 38 bool operator == (const Point& p1, const Point& p2) {
 39     return p1.x == p2.x && p1.y == p2.y;
 40 }
 41 
 42 double max(double a,double b)
 43 {
 44      return a-b>eps?a:b;
 45 }
 46 
 47 Point read_point()
 48 {
 49     Point p;
 50     scanf("%lf %lf",&p.x,&p.y);
 51     return p;
 52 }
 53 
 54 double DistanceToLine(Point P,Point A,Point B)//点到直线的距离
 55 {
 56     Vector v1=B-A,v2=P-A;
 57     return fabs(Cross(v1,v2))/Length(v1);
 58 }
 59 
 60 vector<Point> ConvexHull(vector<Point>& p)
 61 {
 62     sort(p.begin(), p.end());
 63     p.erase(unique(p.begin(), p.end()), p.end());
 64     int i,n = p.size();
 65     int m = 0;
 66     vector<Point> ch(n+1);
 67     for(i = 0; i < n; i++) {
 68         while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
 69         ch[m++] = p[i];
 70     }
 71     int k = m;
 72     for(i = n-2; i >= 0; i--) {
 73         while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
 74         ch[m++] = p[i];
 75     }
 76     if(n > 1) m--;
 77     ch.resize(m);
 78     return ch;
 79 }
 80 
 81 
 82 bool is_ok(vector<Point> &p,Point A,Point B)
 83 {
 84     double upmax=0,downmax=0,len;
 85     for(int i=0;i<p.size();i++)
 86     {
 87         len=DistanceToLine(p[i],A,B);
 88         if(len-2*r>eps) return false;
 89         if(Cross(A-B,A-p[i])>eps) upmax=max(upmax,len);
 90         else downmax=max(downmax,len);
 91     }
 92     if(2*r-upmax-downmax>eps || fabs(upmax+downmax-2*r)<eps) return true;
 93     else return false;
 94 }
 95 
 96 bool solve(vector<Point>& points)
 97 {
 98     vector<Point> p = ConvexHull(points);
 99     int i,j,n = p.size();
100     if(n<=2) return true;
101     for(i=0;i<n;i++)
102     {
103         for(j=i+1;j<n;j++)
104         {
105             if(is_ok(p,p[i],p[j])) return true;
106         }
107     }
108     return false;
109 }
110 
111 int main()
112 {
113     int n,i,t;
114     vector<Point> P;
115     scanf("%d",&t);
116     while(t--)
117     {
118         P.clear();
119         scanf("%d %lf",&n,&r);    
120         for(i=0;i<n;i++)
121         {
122             P.push_back(read_point());
123         }
124         if(n<=2) 
125         {
126             printf("Yes\n");
127             continue;
128         }
129         if(solve(P)) printf("Yes\n");
130         else printf("No\n");
131     }
132     return 0;
133 }
View Code

 

K - Practical Number
Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu
Submit Status
Appoint description: 

Description

In number theory, a practical number is a positive integer n such that all smaller positive integers can be represented as sums of distinct divisors of n.
For example, 12 is a practical number because all the numbers from 1 to 11 can be expressed as sums of its divisors 1, 2, 3, 4, and 6: as well as these divisors themselves, we have 5 = 3 + 2, 7 = 6 + 1, 8 = 6 + 2, 9 = 6 + 3, 10 = 6 + 3 + 1, and 11 = 6 + 3 + 2. The first few practical numbers are: 1, 2, 4, 6, 8, 12, 16, 18, 20, 24, 28, 30, 32, 36, 40, 42, 48, 54, 56, 60.
Given a positive integer ntest if it is a practical number.

Input

The first line contains the number of test cases  T (1   T    200).
For each test case, there is only one line with an integer n (1 ≤  n ≤ 1018) as defined above.

Output

For each test case, output “Yes (without quotation marks) in one line if n is a practical number. Otherwise, output No (without quotation marks) instead.

Sample Input

10
1
2
3
4
5
6
7
8
9
10

Sample Output

Yes
Yes
No
Yes
No
Yes
No
Yes
No
No

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

typedef long long LL;

const int maxn=1000005;
int prime[maxn],N;
bool flag[maxn];

struct point
{
    LL i,c;
}p[100];

void init()
{
    int i,j;N=0;
    memset(flag,true,sizeof(flag));
    for(i=2;i<maxn;i++)
    {
        if(flag[i]) prime[N++]=i;
        for(j=0;j<N&&i*prime[j]<maxn;j++)
        {
            flag[prime[j]*i]=0;
            if(i%prime[j]==0)
                break;
        }
    }
}

LL Pow(LL a,LL b)
{
    LL ret=1;
    while(b)
    {
        if(b&1) ret=ret*a;
        a=a*a;
        b>>=1;
    }
    return ret;
}

void solve()
{
    int num=1,i=0,top;
    LL n,n1=1;
    scanf("%lld",&n);
    top=(int)sqrt(n*1.0);
    if(n<=2){ printf("Yes\n");return ;}
    if(n%2){ printf("No\n");return ;}
    while(prime[i]<=top && i<N)
    {
        if(n%prime[i]==0)
        {
            p[num].i=prime[i];p[num].c=0;
            while(n%prime[i]==0)
            {
                p[num].c++;
                n/=prime[i];
            }
            if(num>1)
            {
                n1*=(Pow(p[num-1].i,p[num-1].c+1)-1)/(p[num-1].i-1);
                if(n1+1<prime[i]){ printf("No\n"); return ;}
            }
            num++;
        }
        i++;
    }
    if(n>1)
    {
        p[num].i=n;p[num].c=1;
        n1*=(Pow(p[num-1].i,p[num-1].c+1)-1)/(p[num-1].i-1);
        if(n1+1<p[num].i){ printf("No\n"); return ;}
    }
    printf("Yes\n");
    return ;
}

int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--)
        solve();
    return 0;
}
View Code

 

 

posted on 2014-04-25 11:16  雄..  阅读(359)  评论(0编辑  收藏  举报

导航