2020 Multi-University Training Contest 10

Contents

概要

01 02 03 04 05 06 07 08 09 10 11
总体 ? ? ?
wzgy
csz ?
wh ? ?

比赛地址

2020 Multi-University Training Contest 10

题目

1007. Coin Game

题目大意

N 个机器,每个机器按第一次可以获得 a[i],按第二次可以获得 b[i],按第三次可以获得 a[i],后面再按不获得。

问:按第一次至第 k 次,分别至多能获得多少?

解题思路

每个 machine 给予的硬币可以等价成, 一个重量为 1 的价值为 a[i] 的硬币, 以及一个重量为 2 的价值为 a[i] + b[i] 的硬币, 这两硬币之间没有相互影响. (对于第 i 个 machine, 如果只取一个, 等价于取重量为 1 的那枚, 如果取了前两个, 等于取了重量为 2 的那枚, 如果三个都取了, 等价于同时取了重量为 1 和重量为 2 的那枚)。

可以按性价比从大到小排序, 然后选性价比最高的那些, 直到取到的硬币总重量不小于 k. 如果这时候取的硬币总重量恰好为 k, 那么这一定就是最优取法. 否则就是总重量恰好为 k + 1, 这时候我们需要丢弃一枚性价比最低的重量为 2 的硬币, 拿多一枚重量为 1 的硬币。

然后 dp 即可。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
int read()
{
    int res = 0, f = 0; char c = getchar();
    while(!isdigit(c) && c != '-') c = getchar();
    if(c == '-') f++, c = getchar();
    while(isdigit(c)) res = (res<<3)+(res<<1)+(c^48), c = getchar();
    return f ? -res : res;
}

const int maxn = 5e6+10;
const int threshold = 10000000;
const LL inf = 4e18;

int n, m, a[maxn], b[maxn];
unsigned long long k1, k2;

unsigned long long xorShift128Plus()
{
    unsigned long long k3 = k1, k4 = k2;
    k1 = k4;
    k3 ^= (k3 << 23);
    k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
    return k2 + k4;
}

void gen(int n, unsigned long long _k1, unsigned long long _k2)
{
    k1 = _k1, k2 = _k2;
    for(int i = 1; i <= n; i++)
    {
        a[i] = xorShift128Plus() % threshold + 1;
        b[i] = xorShift128Plus() % threshold + 1;
        b[i] += a[i];
    }
}

int main()
{
    unsigned long long t1, t2;
    while(~scanf("%d%d%llu%llu", &n, &m, &t1, &t2))
    {
        gen(n, t1, t2);
        sort(a+1, a+n+1, greater<int>());
        sort(b+1, b+n+1, greater<int>());
        int x = 1, y = 0;
        LL ans = a[1], sum = a[1];
        for(int i = 2; i <= m; i++)
        {
            LL tmp1 = -inf, tmp2 = -inf;
            if(x < n) tmp1 = a[x+1];
            if(x >= 1 && y < n) tmp2 = b[y+1]-a[x];
            if(tmp1 > tmp2) x++, sum += tmp1;
            else x--, y++, sum += tmp2;
            ans ^= sum;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

1010. Tic-Tac-Toe-Nim

题目大意:

给你一个 3\times 3 的数字表格,每个格子中有一定数量的石子。每次可以拿掉其中一堆石子的 1 至全部个。当某一行石子被拿光时,游戏结束,最后拿石子的玩家获胜。

为了加快游戏进程,要求两位玩家第一次必须拿光一堆石子。问,先手玩家第一次拿的堆中,有多少是可以保证必胜的?

问题分析:

首先,两人最开始拿光的两堆不能在同一行或者同一列,否则先手只需要拿光这一行(列)的另一堆得全部石子即可获胜。不妨设拿掉后的局面如下:

\begin{matrix}
0&a_{12}&a_{13} \cr a_{21}&a_{22}&0 \cr a_{31}&a_{32}&a_{33}
\end{matrix}

那么最终的状态为:

\begin{matrix}
0&1&1 \cr 1&1&0 \cr 1&0&1
\end{matrix}

到这个状态后,先手不论怎么走都会失败;如果有人破坏这个局面(将某个 1 提前变成 0),则另一方只需将此行(列)中另一堆拿光即可获胜。

问题转化为了 7 堆石子,其中 6 堆的石子数量为 a_{ij}-1,与两个开始被拿光的堆不同行列的堆石子数量为 a_{ij} 的一个普通 Nim 游戏。

AC代码:

#include <bits/stdc++.h>
using namespace std;
int a[4][4];

int id(int i, int j) {
    i--, j--;
    int idx = 3 - i % 3 - j % 3;
    int idy = 3 - i / 3 - j / 3;
    return 3 * idy + idx + 1;
}

bool ok(int i, int j) {
    return (i % 3 != j % 3) && ((i - 1) / 3 != (j - 1) / 3);
}

bool judge(int i) {
    for (int j = 1; j <= 9; j++) {
        if (!ok(i, j)) continue;
        int x = id(i, j);
        int ans = 0;
        for (int k = 1; k <= 9; k++) {
            if (k == i || k == j) continue;
            int now = a[(k - 1) / 3 + 1][(k - 1) % 3 + 1];
            ans ^= (k == x ? now : now - 1);
        }
        if (ans == 0) return false;
    }
    return true;
}

int main()
{
    int T; scanf("%d", &T);
    while (T--) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                scanf("%d", &a[i][j]);
            }
        }
        int cnt = 0;
        for (int i = 1; i <= 9; i++) {
            if (judge(i)) {
                cnt++;
            }
        }
        printf("%d\n", cnt);
    }
    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇