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

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

Description

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

Input

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

Output

对于每组测试数据,输出一个字符串表示这个人的体重是否正常。如果这个人的体重过重,输出“ Over weight”(不包含引号);如果这个人体重过轻,输出“ 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: System Crawler  (2014-04-22)

Description

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

Input

输入的第一行包含一个整数 T  (1  ≤   T   ≤   200 ),表示一共有 T 组测试数据。
对于每组测试数据,第一行包含4个整数 x A ,  y A ,  v Ax ,  v Ay  (-10 3   ≤   x A ,  y A ,  v Ax ,  v Ay   ≤  10 3 ),表示 t  = 0时刻 A 的坐标为( x A ,  y A ), A 的速度在 x 轴方向上的分量为 v Ax ,在 y 轴上的分量为 v Ay 。第二行包含四个整数 x B ,  y B ,  v Bx ,  v By  (-10 3   ≤   x B ,  y B ,  v Bx ,  v By   ≤  10 3 ),以相同的方式给出了 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: System Crawler  (2014-04-20)

Description

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

Input

输入的第一行包含一个整数 T  ( T  > 0) ,表示一共有 T 组测试数据。
对于每组测试数据,第一行包含两个整数 N ,  D  (1 ≤  N  ≤ 10 5 , 1  ≤  D  ≤ 10 9 ) 。第二行包含 N 个整数 a 1 ,  a 2 , ...,  a N  (0 <  a 1  <  a 2  < ... <  a N  < 10 9 ) ,其中 a i  (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: System Crawler  (2014-04-20)

Description

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

Input

输入的第一行包含一个整数 T  ( T  > 0),表示一共有 T 组测试数据。
对于每组测试数据,第一行包含一个整数 n  (1  ≤   n   ≤  10 5 )。第二行包含2 n 个整数 a 1 ,  b 1 ,  a 2 ,  b 2 , ...,  a n ,  b n  (0 <  a 1   ≤   b 1  <  a 2   ≤   b 2  < ... <  a n   ≤  b n  < 10 9 ),表示 A  = [ a 1 ,  b 1 ]  ∪  [ a 2 ,  b 2 ]  ∪  ...  ∪  [ a n ,  b n ]。第三行包含一个整数 m  (1  ≤   m   ≤  10 5 )。第四行包含2 m 个整数 c 1 ,  d 1 ,  c 2 ,  d 2 , ...,  c m ,  d m  (0 <  c 1   ≤  d 1  <  c 2   ≤   d 2  < ... <  c m   ≤   d m  < 10 9 ),表示 B  = [ c 1 ,  d 1 ]  ∪  [ c 2 ,  d 2 ]  ∪  ...  ∪  [ c m ,  d m ]。
这里[ x ,  y ]表示由 x ,  y 之间(包含 x ,  y )所有整数组成的集合。

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: System Crawler  (2014-04-20)

Description

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

Input

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

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: System Crawler  (2014-04-20)

Description

There  are several circles  in  the plane, and they have the same radius.  I f 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  N ,  R  (1  ≤   N   ≤  10 5 ,  1   ≤   R  ≤  10 4 ),  giving the number of circles and the radius of these circles. Then follow  N  lines with two integers  x ,  y  (0  ≤  x ,  y  < 10 9 ), 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: System Crawler  (2014-04-22)

Description

In  number theory , a practical number  i s 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 n ,  test  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  ≤ 10 18 ) 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

 

 

转载于:https://www.cnblogs.com/xiong-/p/3688311.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值