CF R334 div2

Codeforces R334 div2
过题数:1
A:
题意:模拟CF的算分机制
思路:简单计算签到
源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
    int m[5];
    int w[5];
    int s1, s2;
    while(scanf("%d", &m[0]) != EOF){
        for(int i = 1 ; i < 5 ; i++)    scanf("%d", &m[i]);
        for(int i = 0 ; i < 5 ; i++)    scanf("%d", &w[i]);
        scanf("%d%d", &s1, &s2);
        int ans = 0;
        int x = 500;
        for(int i = 0 ; i < 5 ; i++){
            ans += max(x / 10 * 3, x - x / 250 * m[i] - 50 * w[i]);
            x += 500;
        }
        ans += 100 * s1 - 50 * s2;
        ans = max(ans, 0);
        printf("%d\n", ans);
    }
    return 0;
}

B:
题意:把n个物品(<=1e5)分配到k个箱子里(2 * k <= 1e5),可以两个物品放在一个箱子里面。每个物品有体积(<=1e6),问需要的最大的箱子体积多少。
思路:贪心,先按照一个物品一个箱子分配知道2 * k == n,即箱子必须要放两个物品的时候。这时候对于此时剩下的最大物品,它取第一个物品即剩下的最小物品时对箱子体积要求最低。然后就完了。
源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int MAXN = 100000 + 5;
int s[MAXN];
int main()
{
    int n, k;
    while(scanf("%d%d", &n, &k) != EOF){
        for(int i = 1 ; i <= n ; i++)   scanf("%d", &s[i]);
        if(n == 1){
            printf("%d\n", s[1]);
            continue;
        }
        int ans = 0;
        while(k * 2 > n && n > 0){ ///现场没加n>0判断怒WA
            ans = max(ans, s[n]);
            n--;
            k--;
        }
        int head = 1 ,rear = n;
        while(head < rear){
            ans = max(ans, s[head] + s[rear]);
            head++, rear--;
        }
        printf("%d\n", ans);
    }
    return 0;
}

C:
题意:一段01串(len<=1e5)。现在有一种操作使得一串01串变成10串(即0->1,1->0),最多使用一次。问变换后能得到01串中,按顺序但不一定连续抽取0和1组成010101类似的串,这样串的最大长度多少。
思路:把原01串中连续的0和1看成一个带有权重的字符。这样原串就转化为一个标准的0101串。
然后分类讨论。如果有一个字符权重大于2,比如111,它就能给答案增加2比如变成101(多增0和1)。如果有两个及以上字符权重等于2,比如11010100,它可以这样转换1 010101 0,然后答案也可以增加2。最不济的情况是只有一个字符权重为2其余为1,则只能给答案增加1。Else 不进行任何操作。
具体构建模型可以用一个数轴来表示区间大小。
源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 100000 + 5;
int len[MAXN], cnt;
char str[MAXN];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        scanf("%s", str);
        if(n == 1){
            printf("1\n");
            continue;
        }
        memset(len, 0, sizeof(len));
        cnt = 1;
        int pre = str[0] - '0';
        len[cnt] = 1;
        for(int i = 1 ; i < n ; i++){
            if(str[i] - '0' == pre){
                len[cnt]++;
            }
            else{
                pre = str[i] - '0';
                len[++cnt] = 1;
            }
        }
        if(cnt == 1){
            if(len[1] > 2)  printf("3\n");
            else if(len[1] == 1)    printf("1\n");
            else    printf("2\n");
            continue;
        }
        int ans = cnt;
        int ok1 = 0;
        int flag = 0;
        for(int i = 1 ; i <= cnt ; i++){
            if(len[i] >= 2) ok1++;
            if(len[i] > 2)  flag = 1;
        }
        if(ok1 >= 2 || flag)    ans += 2;
        else if(ok1 == 1)   ans++;
        printf("%d\n", ans);
    }
    return 0;
}

D:(赛中无思路)
题意:给一个函数f(k*x%p) = k*f(x)%p,现在数的范围为[0,p-1],问有几种分配f[i]的方式使得满足上面这个函数。
思路:
感谢并膜拜q巨orz~
由函数可知f(k*x%p)可以由f(x)推出,故可知它最终会构成一个环,即确定了f(x)的值,就可以推出其他和f(x)在同一个环上的值。
那么现在要找有几个环。设一个环的长度为r,则有k^r * x == x即k^r == 1(modp)。暴力查找就可以。
因为剩余不确定的数为p-1个(0这个数可由f(0) = k * f(0)推出恒为0)可用类似唯一分解定理的定理证明(p-1) % r = 0。
然后答案为p ^ ((p-1) / r))。
以上均假设k>2的情况(奇质数才有以上性质)。K=0和1特判。k为2的特判可以与k>2的情况合并所以就一起写了。
源码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define LL long long
#define inf (1000000007)
LL ppow(LL a, LL x, LL mod)
{
    LL ans = 1;
    while(x){
        if(x & 1)   ans = (ans * a) % mod;
        a = (a * a) % mod;
        x >>= 1;
    }
    return ans;
}
int main()
{
    LL n, k;
    while(scanf("%I64d%I64d", &n, &k) != EOF){
        LL ans = 0;
        if(k == 0)  ans = ppow(n, n - 1, inf);
        else if(k == 1){
            ans = ppow(n, n, inf);
        }
        else{
            LL r = 1;
            for(int i = 2 ; i <= n ; i++){ ///此处不能从1开始
                if(ppow(k, i, n) == 1){
                    r = i;
                    break;
                }
            }
            ans = ppow(n, (n - 1) / r, inf);
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(CF R334 div2)