2016-2017 ACM-ICPC CHINA-Final (慢慢做慢慢更新)

用力戳我下载全套题的pdf~

用力戳我直达cf评测系统~

目前已做出:

Problem A. Number Theory Problem

Problem D. Ice Cream Tower

Problem L. World Cup

题解:

A。简单数论

1
2
3
4
5
6
7
8
9
10
11
12
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t, n, Case;
    scanf("%d",&t);
    for(Case = 1; Case <= t; Case++)
    {
        scanf("%d",&n);
        printf("Case #%d: %d ",Case, n / 3);
    }
}

D。二分 + 贪心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a[300030];
ll tp[300030];//judge时用
int t, n ,k;
bool judge(int x)
{
    memset(tp,-1,sizeof(tp));
    for(int i = 0; i < x; i++)
        tp[i] = a[i];
    int pos = x;
    for(int i = 2; i <= k; i++) //层数
    {
        for(int j = 0; j < x; j++) //每一层有 x 个
        {
            pos = lower_bound(a + pos, a + n, tp[j] * 2) - a;
            if(pos + 1 > n)
                return false;
            tp[j] = a[pos]; //更新当前最底层
            pos++; //下一次 从 下一个数开始搜
        }
    }
    return true//叠加成功则返回true
}
int main()
{
    int Case;
    scanf("%d",&t);
    for(Case = 1; Case <= t; Case++)
    {
        memset(a,0,sizeof(a));
        scanf("%d%d",&n, &k);
        for(int i = 0; i < n; i++)
            scanf("%I64d",a + i);
        sort(a, a + n);
        int low = 0, high = n / k, mid;
        while(low < high)
        {
            int mid = (low + high + 1) >> 1;
            if(judge(mid))
                low = mid; //搜右界
            else
                high = mid - 1;
        }
        printf("Case #%d: %d ",Case, low);
    }
}

L。模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
#define MEM(a,b) memset(a,b,sizeof(a))
using namespace std;
int sco[12][12][12][12];
void init()
{
    MEM(sco,0);
    int op1[]={3,1,0}; // a a a b b c
    int op2[]={0,1,3}; // b c d c d d
    //枚举六场比赛
    for(int k1 = 0; k1 <= 2; k1++)
    for(int k2 = 0; k2 <= 2; k2++)
    for(int k3 = 0; k3 <= 2; k3++)
    for(int k4 = 0; k4 <= 2; k4++)
    for(int k5 = 0; k5 <= 2; k5++)
    for(int k6 = 0; k6 <= 2; k6++)
    {
        //根据op1 op2的注释统计分值
        int A = op1[k1] + op1[k2] + op1[k3];
        int B = op2[k1] + op1[k4] + op1[k5];
        int C = op2[k2] + op2[k4] + op1[k6];
        int D = op2[k3] + op2[k5] + op2[k6];
        sco[A][B][C][D] ++;  //累计最终榜单
    }
}
int main()
{
    int n, a, b, c, d;
    init();  //只需要暴力跑一次就行
    scanf("%d",&n);
    for(int Case = 1; Case <= n; Case++)
    {
        scanf("%d%d%d%d",&a, &b, &c, &d);
        if(sco[a][b][c][d] == 0)
            printf("Case #%d: Wrong Scoreboard ",Case);
        else if(sco[a][b][c][d] == 1)
            printf("Case #%d: Yes ",Case);
        else
            printf("Case #%d: No ",Case);
    }
}
原文地址:https://www.cnblogs.com/bestwzh/p/6408115.html