TOYOTA MOTOR CORPORATION Programming Contest 2022(AtCoder Beginner Contest 270)(DP + 二分 + 最小生成树(超源)

A. 1-2-4 Test

Problem Statement

There was an exam consisting of three problems worth 11, 22, and 44 points.

Takahashi, Aoki, and Snuke took this exam. Takahashi scored AA points, and Aoki scored BB points.

Snuke solved all of the problems solved by at least one of Takahashi and Aoki, and failed to solve any of the problems solved by neither of them.

Find Snuke’s score.

It can be proved that Snuke’s score is uniquely determined under the Constraints of this problem.

自己写的比较麻烦,看了题解才知道可以写这么简单。

题解代码

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

int main() {
	int a, b;
	cin>>a>>b;
	cout<<(a|b)<<endl;
	return 0;
}

我的代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>

using namespace std;


vector<int> get(int a) {
    if (a == 0) return {};
    if (a == 1) return {1};
    if (a == 2) return {2};
    if (a == 3) return {1, 2};
    if (a == 4) return {4};
    if (a == 5) return {1, 4};
    if (a == 6) return {2, 4};
    if (a == 7) return {1, 2, 4};
}

int main()
{
    int a, b, ans = 0;
    scanf("%d%d", &a, &b);
    
    auto p = get(a);
    auto q = get(b);
    
    p.insert(p.end(), q.begin(), q.end());
    set<int> s(p.begin(), p.end());
    
    for (auto c : s)
        ans += c;
    printf("%d\n", ans);
    return 0;
}

B.Hammer

Problem Statement

Takahashi is at the origin of a number line. He wants to reach a goal at coordinate XX.

There is a wall at coordinate YY, which Takahashi cannot go beyond at first.
However, after picking up a hammer at coordinate ZZ, he can destroy that wall and pass through.

Determine whether Takahashi can reach the goal. If he can, find the minimum total distance he needs to travel to do so.

简单模拟

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>

using namespace std;

int main()
{
    int a, b, z,  ans = 0;
    scanf("%d%d%d", &a, &b, &z);
   
    if (abs(a) <= abs(b)) ans = abs(a);
    else {
        if (a * b < 0) ans = abs(a);
        else {
            if (b * z < 0) ans = 2 * abs(z) + abs(a);
            else {
                if (abs(b) < abs(z)) ans = -1;
                else ans = abs(a);
            }
        }
    }
    
    printf("%d\n", ans);
    return 0;
}

C.Simple path

Problem Statement

There is a tree TT with NN vertices. The ii-th edge (1\leq i\leq N-1)(1≤iN−1) connects vertex U_iU**i and vertex V_iV**i.

You are given two different vertices XX and YY in TT. List all vertices along the simple path from vertex XX to vertex YY in order, including endpoints.

It can be proved that, for any two different vertices aa and bb in a tree, there is a unique simple path from aa to bb.

我这里用的是BFS,用dist来记录路径。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

const int N = 200100;

int n, x, y;
int dist[N];
vector<int> g[200010];

void bfs()
{
    memset(dist, -1, sizeof dist);
    queue<int> q;
    
    q.push(x);
    
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        if (u == y) return;
        
        for (auto c : g[u])
        {
            if (dist[c] != -1) continue;
            dist[c] = u;
            q.push(c);
        }
    }
}

int main()
{
    scanf("%d%d%d", &n, &x, &y);
    
    for (int i = 0; i < n - 1; i ++)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
    
    bfs();
    
    vector<int> res;
    while(y != x)
    {
        res.push_back(y);
        y = dist[y];
    }
    res.push_back(x);
    reverse(res.begin(), res.end());
    
    for (auto c : res)
    {
        printf("%d ", c);
    }
    printf("\n");
    return 0;
}

D.Stones

Problem Statement

Takahashi and Aoki will play a game of taking stones using a sequence ( A 1 , … , A K ) (A_1, \ldots, A_K) (A1,,AK).

There is a pile that initially contains NN stones. The two players will alternately perform the following operation, with Takahashi going first.

  • Choose an A i A_i Ai that is at most the current number of stones in the pile. Remove A_iA**i stones from the pile.

The game ends when the pile has no stones.

If both players attempt to maximize the total number of stones they remove before the end of the game, how many stones will Takahashi remove?

DP[n]= the number of stones that the first player can take if the game starts with a pile with n stones.

The transition is:

D P [ n ] = max ⁡ { A i + ( n − A i ) − D P [ n − A i ] ∣ A i ≤ n } . DP[n]=\max \{A_i+(n-A_i)-\mathrm{DP}[n-A_i] \mid A_i\leq n\}. DP[n]=max{Ai+(nAi)DP[nAi]Ain}.

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 10010, K = 110;

int n, k;
int a[K];
int dp[N];

int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 0; i < k; i ++) scanf("%d", a + i);
    
    for (int i = 1; i <= n; i ++)
        for (int j = 0; j < k; j ++)
            if (i >= a[j])
                dp[i] = max(dp[i], a[j] + i - a[j] - dp[i - a[j]]);
        
    printf("%d\n", dp[n]);
    return 0;
}

E. Apple Baskets on Circle

Problem Statement

There are N baskets numbered 1, 2, , N arranged in a circle.
For each 1\leq i \leq N-11≤iN−1, basket i+1i+1 is to the immediate right of basket ii, and basket 11 is to the immediate right of basket NN.

Basket ii now contains A_iA**i apples.

Takahashi starts in front of basket 11 and repeats the following action.

  • If the basket he is facing contains an apple, take one and eat it. Then, regardless of whether he has eaten an apple now, go on to the next basket to the immediate right.

Find the number of apples remaining in each basket when Takahashi has eaten exactly KK apples in total.

先二分找到Takahashi走过的最大圈数,然后用O(N)的时间对每个位置上的苹果做减法,最后将剩余的苹果进行分发。

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long LL;

const int N = 100100;

LL a[N];
LL n;
LL k;

bool check(LL m)
{
    LL ans = 0;
    for (int i = 0; i < n; i ++)
        ans += min(m, a[i]);
    return ans <= k;
}

int main()
{
    scanf("%d%lld", &n, &k);
    
    for (int i = 0; i < n; i ++)
        scanf("%lld", a + i);
    
    LL l = 0, r = 1e12;
    while(l < r)
    {
        LL mid = (l + r + 1) >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    
    for (int i = 0; i < n; i ++)
    {
        LL d = min(l, a[i]);
        a[i] -= d;
        k -= d;
    }
    
    for (int i = 0; k > 0; i ++)
    {
        if (a[i]) a[i]--, k --;
    }
    
    for (int i = 0; i < n; i ++)
        printf("%lld ", a[i]);
    printf("\n");
    
    return 0;
}

F.Transportation

Problem Statement

The Republic of AtCoder has NN islands. Initially, none of the islands has an airport or harbor, and there is no road between any two of them. Takahashi, the king, will provide some means of transportation between these islands. Specifically, he can do the following operations any number of times in any order.

  • Choose an integer ii such that 1\leq i\leq N1≤iN and pay a cost of X_iX**i to build an airport on island ii.
  • Choose an integer ii such that 1\leq i\leq N1≤iN and pay a cost of Y_iY**i to build a harbor on island ii.
  • Choose an integer ii such that 1\leq i\leq M1≤iM and pay a cost of Z_iZ**i to build a road that bidirectionally connects island A_iA**i and island B_iB**i.

Takahashi’s objective is to make it possible, for every pair of different islands UU and VV, to reach island VV from island UU when one can perform the following actions any number of times in any order.

  • When islands SS and TT both have airports, go from island SS to island TT.
  • When islands SS and TT both have harbors, go from island SS to island TT.
  • When islands SS and TT are connected by a road, go from island SS to island TT.

Find the minimum total cost Takahashi needs to pay to achieve his objective.

  1. 这道题和普通的超级源点题不一样,该题中不仅有机场,还有港口。
  2. 所以分四种情况:
    1. 没有机场、港口
    2. 有机场无港口
    3. 有港口无机场
    4. 有机场有港口
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

typedef long long LL;

const int N = 200000 + 100;
const LL INF = 3e18;

typedef struct Edge{
    int x, y, w;
    bool operator<(const Edge& t) const {
        return w < t.w;
    }
}E;

int a[N], b[N], c[N], d[N], f[N];
vector<E> g;
int n, m;
int fa[N];


int find(int x)
{
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

LL solve()
{
    sort(g.begin(), g.end());
    
    for (int i = 0; i <= n + 2; i ++) fa[i] = i;
    
    LL res = 0;
    for (auto t : g)
    {
        int f1 = find(t.x), f2 = find(t.y);
        if (f1 != f2) {
            fa[f1] = f2;
            res += t.w;
        }
    }
    for (int i = 1; i <= n; i ++)
        if (find(i) != find(1))
            return INF;
    return res;
}


int main()
{
    scanf("%d%d", &n, &m);
    
    for (int i = 1; i <= n; i ++) scanf("%d", a + i);
    for (int i = 1; i <= n; i ++) scanf("%d", b + i);
    
    for (int i = 0; i < m; i ++)
        scanf("%d%d%d", c + i, d + i, f + i);
    
    LL ans = INF;
    for (int i = 0; i < 4; i ++)
    {
        g.clear();
        for (int j = 0; j < m; j ++) g.push_back({c[j], d[j], f[j]});
        if (i & 1) for (int j = 1; j <= n; j ++) g.push_back({j, n + 1, a[j]});
        if (i & 2) for (int j = 1; j <= n; j ++) g.push_back({j, n + 2, b[j]});
        ans = min(ans, solve());
    }
    
    printf("%lld\n", ans);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Honyelchak

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值