欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2019中国大学生程序设计竞赛-女生专场(重现赛)

程序员文章站 2022-07-15 16:10:13
...

Ticket

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 674 Accepted Submission(s): 373

Problem Description
北京地铁票每月的打折规则为:本次乘车前总消费不足 100 元本次不打折,满 100 元不足 150 元本次打8 折,满 150 元不足 400 元本次打 5 折,已满 400 元后本次不打折,已知 wls 每次出行的原票价,请问实际的花费是多少?

Input
输入包含两行。第一行一个整数 n 代表 wls 将要出行的次数。第二行 n 个正整数, ai 代表每次出行的票的原价,wls 是按照输入顺序依次出行的。
0 ≤ n ≤ 1, 000
0 < ai ≤ 1, 000

Output
一行一个数,代表实际的花费,保留小数点后两位小数。

Sample Input

3
100 20 20

Sample Output
132.00
HINT
模拟一下,签到题
Code:

#include<stdio.h>
#include<string.h>
int main()
{
    int n,a;
    scanf("%d",&n);
    scanf("%d",&a);
    double sum=a;
    for(int i=1; i<n; i++)
    {
        scanf("%d",&a);
        if(sum>=0&&sum<100)
            sum+=a;
        else if(sum>=100&&sum<150)
        {
            sum+=0.8*a;
        }
        else if(sum>=150&&sum<400)
            sum+=0.5*a;
        else
            sum+=a;
    }
    printf("%.2lf\n",sum);
    return 0;
}

Gcd

Problem Description
wls 有一个整数 n,他想将 1 − n 这 n 个数字分成两组,每一组至少有一个数,并且使得两组数字的和的最大公约数最大,请输出最大的最大公约数。

Input
输入一行一个整数 n。
2 ≤ n ≤ 1, 000, 000, 000

Output
输出一行一个整数表示答案。

Sample Input

6

Sample Output

7

HINT
gcd=(a+b)/k;所以把他们累加然后从2开始遍历到n/2有就输出就是最大公因数
Code:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int sum=(1+n)*n/2;
        for(int i=2; i<=n/2; i++)
        {
            if(sum%i==0)
            {
                printf("%d\n",sum/i);
                break;
            }
        }
    }
    return 0;
}

Circle

Problem Description
在半径为 1 的圆上有 n 个点,它们也是圆的 n 等分点,将每个相邻的 n 等分点相连,组成了一个正 n边形,现在你可以在圆上再增加一个点,使得新的 n + 1 边形的面积最大,请输出最大面积。

Input
输入有多组(不超过 100 组)。
每组数据一行一个整数 n 代表点的数量。
3 ≤ n ≤ 100

Output
每组数据输出一行一个数表示加上一个点后的最大面积,结果保留6位小数。

Sample Input

3

Sample Output

1.732051

HINT
公式题
Code:

#include<stdio.h>
#include<math.h>
#include<string.h>
#define PI acos(-1.0)
int main()
{
    double n;
    while(~scanf("%lf",&n))
    {
        double S=(n-1)/2*sin(2*PI/n)+sin(PI/n);
        printf("%.6lf\n",S);
    }
    return 0;
}

Tangram

Problem Description
一块七巧板有 7 块,现在 wls 想再在七巧板上加 n 条直线将七巧板切分并且使得切出来的块最多,请问最多能有多少块?
2019中国大学生程序设计竞赛-女生专场(重现赛)

Input
输入有多组(不超过 100, 000组)。
每组一行一个正整数 n。
0 ≤ n ≤ 1, 000, 000, 000

Output
每组输出一行一个数代表答案。

Sample Input

1

Sample Output

13

HINT
每次切下来的规律是6+7+8+9+…+(5+n)
所以使用求和公式可以直接推出答案
不过数据有点大所以要用long long
Code:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    long long n;
    while(scanf("%lld",&n)!=EOF)
    {
        printf("%lld\n",7+(6+(n-1)+6)*n/2);
    }
    return 0;
}

Tetris

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 777 Accepted Submission(s): 197
Special Judge

Problem Description
wls 有一个 n ∗ m 的网格,他现在想用俄罗斯方块中的"凸"型密铺它。

2019中国大学生程序设计竞赛-女生专场(重现赛)
一个"凸"型占四个格子,你可以随意把它调成上下左右四个方向中的一个。
密铺的定义是网格中任意一个格子被且只被一个"凸"型铺到,并且这些"凸"型不能铺出网格的边界。
随意输出一组解即可。

Input
一行两个整数 n, m。
1 ≤ n, m ≤ 12

Output
无解输出 no response。
如果有解,输出 n 行,每行 m 个字符。你只能使用 1, 2, 3, 4 这四个字符,由同一字符组成的四连通块被视为一个"凸"型。
如果有多组解,那么输出任意一种即可。

Sample Input

4 4

Sample Output

1113
2133
2243
2444

HINT
就直接把样例往里面套就差不多了
Code:

#include<iostream>
#include<cstdio>
using namespace std;
char w[5][5]= {"1113","2133","2243","2444"};
int main()
{

    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        if(n%4!=0||m%4!=0)
        {
            printf("no response\n");
            continue;
        }
        for(int i=0; i<n; i++)
        {
            int a=i%4;
            for(int j=0; j<m; j++)
            {
                int b=j%4;
                printf("%c",w[a][b]);
            }
            cout<<endl;
        }
    }


    return 0;
}

Clock

Problem Description
wls 有一个钟表,当前钟表指向了某一个时间。
又有一些很重要的时刻,wls 想要在钟表上复现这些时间(并不需要依次复现)。我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会随着秒针按规则转动,wls 想知道秒针至少转动多少角度可以使每个时刻至少都会被访问一次。
注意,时钟上的一种时针分针秒针的组合,可以代表两个不同的时间。

Input
第一行一个整数 n 代表有多少个时刻要访问。
第二行三个整数 h,m,s 分别代表当前时刻的时分秒。
最后n行每一行三个整数 hi,mi,si 代表每个要访问的时刻的时分秒。
1 ≤ n ≤ 86, 400
0 ≤ h, hi < 24
0 ≤ m, mi, s, si < 60

Output
输出一行一个数代表秒钟转的角度,答案保留两位小数。

Sample Input

1
0 1 0
0 1 1

Sample Output

6.00

HINT
把钟表放大全部变成秒的就不用看时针和分针了。
然后减去原始点让他们从0点开始,如果相减后是负的就加上时针的一圈让他转化为秒+126060
然后求出顺时针的角度,逆时针的角度,先顺时针再逆时针的角度,先逆时针再顺时针的角度求最小就行了
先顺再逆和先逆在顺可以一个个点遍历过来,这个点的双倍路径加从零点开始反方向的下一个点的角度(开始想成反方向的第一个点了。。错了好多次)。
Code:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    int h0,m0,s0;
    int h[86500],m[86500],s[86500];
    double t[86500],t0;
    scanf("%d%d%d",&h0,&m0,&s0);
    t0=(double)(h0%12)*60*60+m0*60+s0;
    //printf("%lf\n",t0);
    for(int i=0; i<n; i++)
    {
        scanf("%d %d %d",&h[i],&m[i],&s[i]);
        t[i]=(double)((h[i]%12)*60*60+m[i]*60+s[i])-t0;
        if(t[i]<0)
            t[i]+=12*60*60;
        //printf("%lf\n",t[i]);
    }
    sort(t,t+n);
    double x1=t[n-1];
    double x2=12*60*60-t[0];
    double x3=min(x1,x2),x4=min(x1,x2);
    //printf("%.2lf %.2lf %.2lf\n",x1,x2,x3);
    for(int i=0; i<n; i++)
    {
        x3=min(x3,t[i]*2+12*60*60-t[i+1]);//printf("%.2lf\n",x3);
    }
    for(int i=n-1; i>=0; i--)
    {
        x4=min(x4,2*(12*60*60-t[i])+t[i-1]);//printf("%.2lf %.2lf\n",t[i],t[n-1-i]);
    }
    double x=min(x3,x4);
    printf("%.2lf\n",x*6);
    return 0;
}