Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords(贪心/数学)

题目链接:https://codeforces.com/contest/1366/problem/A

题意

有两个数 $a$ 和 $b$,每次可以选择从一个数中取 $2$,另一个数中取 $1$,问最多可以进行多少次这样的操作。

题解一

比较好想的一种模拟的做法:

  • 较多者每次取两个至二者相等
  • 二者每次同时取三个
  • 如果较多者和较少者有余再加一

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int a, b; cin >> a >> b;
    if (a < b) swap(a, b);
    int sub = min(a - b, b);
    a -= 2 * sub, b -= sub;
    int mi = min(a, b) / 3;
    a -= 3 * mi, b -= 3 * mi;
    cout << sub + 2 * mi + (a >= 2 and b >= 1) << "
";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

题解二

假设 $a ≥ b$,如果 $a ≥ 2b$,此时可以一直两两地取 $a$,答案即 $b$ 。

否则,$a$ 和 $b$ 会轮流取至和小于 $3$,答案即 $lfloor frac{a + b}{3} floor$ 。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int a, b; cin >> a >> b;
    if (a < b) swap(a, b);
    if (a >= 2 * b)
        cout << b << "
";
    else
        cout << (a + b) / 3 << "
";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

题解三

可以理解为题解二的简化版吧...

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int a, b; cin >> a >> b;
    cout << min({a, b, (a + b) / 3}) << "
";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}
原文地址:https://www.cnblogs.com/Kanoon/p/13097799.html