Codeforces Round #382 (Div. 2) A~D

这次cf貌似找规律专场。。。

有点遗憾,C错了两次,D题最后被hack了。。。

C题一开始想简单了,觉得直接判断2 ^ k >= n 输出k就行。。。后来试出个错误,发现不是这么做。。于是推了一个斐波那契。。做D题的时候还剩20分钟,等D题交了时还剩2、3分钟。。。没想到被hack了。。比赛完了才缓过神来,原来忘了判一种情况。。。要是能稳住神做的好点,4道题能涨不少分呢。。。

先写四道题的题解了。。。E题等我会了再写吧尴尬


A:http://codeforces.com/contest/735/problem/A

题意:给出n和k,和一条路,路上有一个G和一个T,其余的.为可走的路,#为障碍物,G每次只能走k步,问是否G能走到T的位置,水题,直接暴即可。。


代码:

# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
const int maxn = 100 + 5;
char s[maxn];
int n, k;

int main(void)
{
    while (~scanf("%d %d", &n, &k)) {
        scanf("%s", s);
        int t1, t2;
        for (int i = 0; i < n; ++i) {
            if (s[i] == 'G') t1 = i;
            if (s[i] == 'T') t2 = i;
        }
        if (t1 > t2) swap(t1, t2);
        bool ok = false;
        for (int i = t1; i <= t2; i += k) {
            if (s[i] == '#') break;
            if (i == t2) {
                ok = true; break;
            }
        }
        if (ok) printf("YES\n");
        else printf("NO\n");
    }

    return 0;
}

B:http://codeforces.com/contest/735/problem/B


题意:给出n个数和n1和n2,从n个数中分别选出n1,n2个数来,得到,n1个数和n2个数的平均值,求这两个平均值的最大和。

思路:要保证k个数的平均值大,那应该要k个数尽量大,并且k尽量小。。。所以,将n个数从大到小sort一遍,如果n1>n2, swap(n1, n2); 然后结果就是前n1个数的平均值加上 n1 到 n1 + n2 这些数的平均值。


代码:


# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int a[maxn];
int n, n1, n2;

bool cmp(int a, int b) {
    return a > b;
}

int main(void)
{
    while (~scanf("%d %d %d", &n, &n1, &n2)) {
        if (n1 > n2) swap(n1, n2);
        for (int i = 0; i < n; ++i) scanf("%d", a + i);
        sort(a, a + n, cmp);
        ll t1 = 0, t2 = 0;
        for (int i = 0; i < n1; ++i) t1 += a[i];
        for (int i = n1; i < n1 + n2; ++i) t2 += a[i];
        double sum = t1 * 1.0 / n1 + t2 * 1.0 / n2;
        printf("%.8lf\n", sum);
    }

    return 0;
}


C:  http://codeforces.com/contest/735/problem/C

题意:有n个队伍比赛,每两个队伍比赛结束后输的人退场,赢的人场次增加1,现在由你来设计比赛顺序(比赛的两个队伍的场次之差不能大于1),使得最后胜利的冠军队伍的参加场次最多,输出这个场次。

思路:

两个队的情况: 0 0 -> 1 三个队的情况:0 0 0 -> 0 1 -> 2 四个队:0 0 0 0 -> 2 0 -> 2 (等价于0 0 0 0 -> 1 1 -> 2

五个队:0 0 0 0 0 -> 2 1 -> 3 8个队: 0 0 0 0 0 0 0 0 ->3 2 -> 4 ......

这么推几组以后,会发现跟斐波那契数列有关系,a = {1, 2, 3, 5, 8}

所以。。先打个斐波那契数列的表,找出小于等于n的最后一个ai,输出下标i即可


代码:


# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long ll;
ll a[100];

void init() {
    a[0] = 1; a[1] = 2;
    for (int i = 2; i < 100; ++i) a[i] = a[i - 1] + a[i - 2];
//    printf("%I64d\n", a[90]);
}

int main(void)
{
    init();
    ll n;
    while (~scanf("%I64d", &n)) {
        for (int i = 0; i < 90; ++i) {
            if (n == a[i]) {
                printf("%d\n", i); break;
            } else if (n < a[i]) {
                printf("%d\n", i - 1); break;
            }
        }
    }

    return 0;
}

D:http://codeforces.com/contest/735/problem/D

题意:给出一个数n,n可以分成a1, a2, ... ai...(n = a1 + a2 + ... + ai + ...) ai不能等于1,设ai的(除了ai以外)的最大约数,则t = k1 + k2 + ... + ki + ... 求t的最小值。。

思路:这题用到了一个数学猜想。。。

哥德巴赫猜想:①任一大于2的偶数都可写成两个素数之和。②任一大于7的奇数都可写成三个素数之和。

小于7的奇数为3, 5,都是素数,所以结果是1。。。

先判断n是否是素数,是素数直接输出1,因为素数的(除其本身)最大约数为1。

如果n不是素数,根据哥德巴赫猜想,n为偶数时,可以分成两个素数,所以结果为2。。。

n为奇数时,先判断是否能分成两个素数之和,如果不能的话。那么结果就是3

判断一个奇数能否分成两个素数之和:

奇数 = 偶数 + 奇数,如果一个奇数能分成两个素数之和的话,那么那个偶数一定是2(偶数只有2是素数),然后判断另一个奇数是否是素数就可以了,即判断n - 2是否是素数,如果是结果就是2,否则结果就是3。。。


D题忘了判断n是奇数的时候可能分成两个素数这种情况了,导致被hack,pity。。。。。


代码:


# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
# include <cmath>
using namespace std;
typedef long long ll;

int main(void)
{
    ll n;
    while (~scanf("%I64d", &n)) {
        bool ok = true;
        for (int i = 2; i <= sqrt(n + 0.5); ++i) {
            if (n % i == 0) {
                ok = false; break;
            }
        }
        if (ok) printf("1\n");
        else {
            if (n % 2 == 0) printf("2\n");
            else {
                n -= 2; bool okk = true;
                for (int i = 2; i <= sqrt(n + 0.5); ++i) {
                    if (n % i == 0) {
                        okk = false; break;
                    }
                }
                if (okk) printf("2\n");
                else printf("3\n");
            }
        }
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值