校赛总结——程序设计竞赛@HIT 2017秋季校赛

这次校赛办的很棒!就是没有小姐姐送气球QAQ。但是对于菜鸡来说,还是很开心啦!混了4题,rank 24,拿了个三等奖,还得了个U盘。也算是对得起自己这几个月的算法学习啦!很多题还不会做,我就把我做出来的放出来。(很水勿喷)

Problem A
64bit Integer Format : %lld Submit

Problem Description

If we have a string s, the length of s is at least 1, and s's characters are all lowercase English letters (between 'a' and 'z'), then we call s a "q-string".
Now we'll give you a "q-string" s0, you need to add "er" at the end of s0.
        Such as "acm", you need to change it into "acmer".
But before you do that, there are two extra steps:
    [step 1] While s0 can be split into (s1 + "e"), s1 is a "q-string", you need to delete the last character of s0.
    [step 2] If s0 can be split into (s1 + c + "y"), s1 is a "q-string" and c is a consonant letter (letter except 'a', 'e', 'i', 'o', 'u'), then you need to change the last character of s0 to 'i'.
        Such as "qwertee", you need to change it into "qwerter" .
        Such as "qwertye", you need to change it into "qwertier".
        Such as "qweraye", you need to change it into "qwerayer".  Input The first line contains an integer T (1<=T<=100), then T cases follow.

In each case:

One line contains one string s0 , the length of s0 is between 1 and
100. s0’s characters are all lowercase English letters.

Output For the i-th case, output one line “Case #i: s”.

You can understand the requirement of string s in the description.

Sample Input 5 e acm qwertee qwertye qweraye

Sample Output Case #1: eer Case #2: acmer Case #3: qwerter Case #4: qwertier Case #5: qwerayer

Hint If you are confused about the sample output, please check out the description carefully.

签到题,题意很简单,但是要看清。先要完成step 1,再完成step 2;注意每一步都对字符串的长度有要求,注意这些,然后模拟一遍就好了。

AC代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
using namespace std;
const int maxl = 105;
char s[maxl];
int main()
{
    int kase;
    scanf("%d", &kase);
    int tt = 0;
    while(kase--)
    {
        scanf("%s", s);
        int len = strlen(s);
        s[len] = '\0';
        printf("Case #%d: ", ++tt);

        while(s[len-1] == 'e' && len > 2)
        {
            s[--len] = '\0';
        }       
        if(len == 1)
        {
            printf("%s", s);
            printf("er\n");
            continue;
        }
        if(len == 2)
        {
            if(s[len-1] == 'e')
            {
                printf("%c", s[0]);
                printf("er\n");
                continue;
            }
            printf("%s", s);
            printf("er\n");
            continue;
        }
        if(s[len-1] != 'y')
        {
            printf("%s", s);
            printf("er\n");
            continue;
        }
        else
        {
            if(s[len-2] == 'a' || s[len-2] == 'e' || s[len-2] == 'i' || s[len-2] == 'o' || s[len-2] == 'u')
            {
                printf("%s", s);
                printf("er\n");
                continue;
            }
            else
            {
                s[len-1] = 'i';
                printf("%s", s);
                printf("er\n");
                continue;
            }
        }
    }
    return 0;
}

Problem B
B - B
Time limit : 1 s Memory limit : 512 mb
Submitted : 349 Accepted : 67
64bit Integer Format : %lld
Submit

Problem Description
For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in non-increasing order first, and then in non-decreasing order, a new number can be obtained by taking the second number from the first one. Repeat in this manner we will soon end up at the number 6174 – the “black hole” of 4-digit numbers. This number is named Kaprekar Constant.

For example, start from 6767, we’ll get:

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
… …

Given any 4-digit number, you are supposed to illustrate the way it gets into the black hole.

Input
In the first line, is a number T (1<= T <= 100), which means the number of test cases.
For each test case, there is one line contains a positive integer N in the range (0, 10000).

Output
If all the 4 digits of N are the same, print in one line the equation “N - N = 0000”. Else print each step of calculation in a line until 6174 comes out as the difference. All the numbers must be printed as 4-digit numbers.

Sample Input
3
6767
2222
6174

Sample Output
Case #1:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
Case #2:
2222 - 2222 = 0000
Case #3:
7641 - 1467 = 6174

也是模拟题,看好给出的数据范围,缺0补0,输出也要补好0,没什么好说了,放代码。
AC代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[5];
int main()
{
    int kase;
    scanf("%d", &kase);
    int tt = 0;
    while(kase--)
    {
        int tmp[4];
        int t1 = 0, t2 = 0;
        int ans = 0;
        scanf("%s", s);
        int len = strlen(s);
        while(len < 4)
        {
            s[len++] = '0';
        }
        printf("Case #%d:\n", ++tt);
        for(int i = 0; i < 4; i++)
        {
            tmp[i] = s[i] - '0';
        }
        while(ans != 6174)
        {
            sort(tmp, tmp+4);
            for(int i = 0; i < 4; i++)
            {
                t1 = t1 * 10 + tmp[i];
            }
            for(int i = 3; i >= 0; i--)
            {
                t2 = t2 * 10 + tmp[i];
            }
            if(t2 == t1)
            {
                printf("%04d - %04d = %04d\n", t2, t1, t2-t1);
                break;
            }
            ans = t2 - t1;
            printf("%04d - %04d = %04d\n", t2, t1, ans);
            int tans = ans;
            for(int i = 0; i < 4; i++)
            {
                tmp[i] = tans % 10;
                tans /= 10;
            }
            t1 = 0;
            t2 = 0;
        }

    }
    return 0;
}

Problem C
C - C
Time limit : 1 s Memory limit : 512 mb
Submitted : 357 Accepted : 30
64bit Integer Format : %lld
Submit

Problem Description
Boss Lee likes frogs,because frogs looks like dogs.
He owns some frogs,but they are too puny.They can’t give him power,so he turn around,go over the mountains,and then finally find a 91-years-old man.
The man has strong power,and also like frogs.
So The man gives Boss Lee a unbelievable magic.
If Boss Lee has two frogs,with x and y power,he can use the magic,and gets a new frog with x+y power,however,he’ll lose two initial frogs.
Though The man has strong magic,he doesn’t want Boss Lee can easily use it without any costs.Boss Leeo he uses a trick.When Boss Lee gets a new frog,with x+y power,he must speak ”Were it to benefit my country I would lay down my life;What then is risk to me?” x+y times.
Boss Lee hate to read that!So he want to know how many times if he wants to get all frogs in one.

Input
There are many test case.The last case must be 0 and you do not need to deal with him.
For each case,first line is an integer n,which mains how many frogs he has.
Next line has n integers,which main each frog power.

Output
For each case,a line includes an integer,that how many times Boss Lee reads the sentence.

Sample Input
3
1 2 3
0 

Sample Output
9

Hint
All data are guaranteed n≤100000
And each frogs power is less than 1000
And in this case,you first magic 1 and 2,speak 3 times,magic 3 and 3,speak 6 times.So total times is 9.

思路很好想,利用贪心,当然是每次取最小的两个数相加,结果会达到最小。这里的问题就是,数据规模不能允许每次操作完都进行一次排序。所以这里我用了优先队列,直接每次取最小的两个,最后再放进队中。就可以轻松解决了。听了学长讲题,他说本想数据的数量级再*10。那么优先队列可能就过不去了。这时候就可以开两个队列,一个存剩余的数,一个存新数。
AC代码如下

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int main()
{
int n;
while(scanf("%d", &n) != EOF && n)
{
int x;
priority_queue<int, vector<int>, greater<int> > q;
for(int i = 0; i < n; i++)
{
scanf("%d", &x);
q.push(x);
}
int ans = 0;
for(int i = 0; i < n-1; i++)
{
int a = q.top();
q.pop();
int b = q.top();
q.pop();
ans += a+b;
q.push(a+b);
}
printf("%d\n", ans);
}
return 0;
}

Problem K
K - K
Time limit : 1 s Memory limit : 512 mb
Submitted : 128 Accepted : 28
64bit Integer Format : %lld
Submit

Problem Description

Remilia Scarlet is the owner of the Scarlet Devil Mansion, she doesn’t like coprime integers. The Scarlet Devil Mansion is now hiring Fairy Maids, there are n candidates, the strength of the i-th candidate is si. The head maid, Izayoi Sakuya, is going to choose some candidates to employ. To please her mistress, the gcd (greatest common divisor) of all chosen candidates’ strengths must not be 1, and she wants to choose as many candidates as possible. Can you help Sakuya find out the maximum number of candidates she can choose?

Input

The first line contains an integer T (1<=T<=10), then T cases follow.

In each case:

The first line contains 1 integer: n (1<=n<=100000), the number of candidates.

The next line contains n integers, where the i-th of them denotes si (1<=si<=100000), the strength of the i-th candidate.

Output

For each case, output one integer, the maximum number of candidates Sakuya can choose.

Sample Input
2
3
2 3 4
5
2 3 4 6 7

Sample Output
2
3

题意就是在一堆数中,找尽可能多的数,使它们的最大公约数大于1,问最多有多少数。
一开始我还想用GCD来做,结果后面发现时间不够。转念一想,这个公约数肯定是素数,那么我只需要素数打表,一个个除来统计就好了。我还利用了一个结论,如果当前使用的约数得到的数个数小于之前的,那么之后的肯定也小于,所以这时候就可以直接break输出结论了。
后面听讲题,学长解释道,数据是随机生成的,那么其中的偶数出现的期望很大,所以只用统计偶数个数就能水过这道题了。。。

AC代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
using namespace std;
const int maxn = 100005;
int s[maxn];
int main()
{
    int kase;
    scanf("%d", &kase);
    while(kase--)
    {
        int n;
        scanf("%d", &n);
        int maxs = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &s[i]);
            if(s[i] > maxs)
                maxs = s[i];
        }

        if(n == 1)
        {
            printf("1\n");
            continue;
        }
        int ans = 2;
        int g = maxn;
        for(int i = 2; i < sqrt(maxs); i++)
        {
            if(i > 3 && (i % 2 == 0 || i % 3 == 0))
                continue;
            if(i > 5 &&  i % 5 == 0)
                continue;
            int tans = 0;
            for(int j = 0; j < n; j++)
            {
                if(s[j] % i == 0)
                    tans++;
            }
            if(tans > ans)
                ans = tans;
            else
                break;
        }
        printf("%d\n", ans);
    }
    return 0;
}

菜的开心!好好准备期末考试!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值