Codeforces1426 E. Rock, Paper, Scissors

Alice and Bob have decided to play the game “Rock, Paper, Scissors”.

The game consists of several rounds, each round is independent of each other. In each round, both players show one of the following things at the same time: rock, paper or scissors. If both players showed the same things then the round outcome is a draw. Otherwise, the following rules applied:

if one player showed rock and the other one showed scissors, then the player who showed rock is considered the winner and the other one is considered the loser;
if one player showed scissors and the other one showed paper, then the player who showed scissors is considered the winner and the other one is considered the loser;
if one player showed paper and the other one showed rock, then the player who showed paper is considered the winner and the other one is considered the loser.
Alice and Bob decided to play exactly 𝑛 rounds of the game described above. Alice decided to show rock 𝑎1 times, show scissors 𝑎2 times and show paper 𝑎3 times. Bob decided to show rock 𝑏1 times, show scissors 𝑏2 times and show paper 𝑏3 times. Though, both Alice and Bob did not choose the sequence in which they show things. It is guaranteed that 𝑎1+𝑎2+𝑎3=𝑛 and 𝑏1+𝑏2+𝑏3=𝑛.

Your task is to find two numbers:

the minimum number of round Alice can win;
the maximum number of rounds Alice can win.
Input
The first line of the input contains one integer 𝑛 (1≤𝑛≤109) — the number of rounds.

The second line of the input contains three integers 𝑎1,𝑎2,𝑎3 (0≤𝑎𝑖≤𝑛) — the number of times Alice will show rock, scissors and paper, respectively. It is guaranteed that 𝑎1+𝑎2+𝑎3=𝑛.

The third line of the input contains three integers 𝑏1,𝑏2,𝑏3 (0≤𝑏𝑗≤𝑛) — the number of times Bob will show rock, scissors and paper, respectively. It is guaranteed that 𝑏1+𝑏2+𝑏3=𝑛.

Output
Print two integers: the minimum and the maximum number of rounds Alice can win.

Examples
inputCopy
2
0 1 1
1 1 0
outputCopy
0 1
inputCopy
15
5 5 5
5 5 5
outputCopy
0 15
inputCopy
3
0 0 3
3 0 0
outputCopy
3 3
inputCopy
686
479 178 29
11 145 530
outputCopy
22 334
inputCopy
319
10 53 256
182 103 34
outputCopy
119 226
Note
In the first example, Alice will not win any rounds if she shows scissors and then paper and Bob shows rock and then scissors. In the best outcome, Alice will win one round if she shows paper and then scissors, and Bob shows rock and then scissors.

In the second example, Alice will not win any rounds if Bob shows the same things as Alice each round.

In the third example, Alice always shows paper and Bob always shows rock so Alice will win all three rounds anyway.

题意:
石头剪刀布,A B每个人出石头、剪刀、布的次数告诉你了,且和均为n,求怎么安排A,B出手顺序,使得A获胜最大或者最少,求数目。

思路:
因为不考虑A失败的影响,所以求最大数目的话,直接A的剪刀对B的布,A的石头对B的剪刀,A的布对B的石头。

最小数目的话,A获胜要尽量少。
则S1要对应S2,R2,R1要对应R2,P2,P1要对应P2,S2。
所以关键就是怎么安排顺序。

赛中我写的是枚举A的出手顺序(S,R,P或者S,P,R或者,R,S,P…,一共6种),虽然A了,但是不知道咋证明。

实际上关键就是S1+R1+P1=S2+R2+P2=n。

所以S1-S2-R2, R1-R2-P2, P1-P2-S2三个中最多只有一个为正数。
比如S1-S2-R2为正数,则说明对于S1有S1-S2-R2的贡献,这个部分填P2。
而P2剩下的部分可以对应R1,P1,所以总的贡献只有S1-S2-R2。

如果都不大于0的话,那就存在分配方案使得A没有获胜。

(事实上这个题也可以用网络流写,3个点的网络流还可行)

参考大佬代码后的写法

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

using namespace std;

int main() {
    int n;scanf("%d",&n);
    int a1,a2,a3;scanf("%d%d%d",&a1,&a2,&a3);
    int b1,b2,b3;scanf("%d%d%d",&b1,&b2,&b3);
    int ans1 = max({0,a1 - b1 - b3,a2 - b2 - b1,a3 - b3 - b2});
    int ans2 = min(a1,b2) + min(a2,b3) + min(a3,b1);
    printf("%d %d\n",ans1,ans2);
    return 0;
}
 

赛中很丑的代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>

using namespace std;

typedef long long ll;
int S1,R1,P1;
int S2,R2,P2;
int num,num2,num3;

int r1,s1,p1;
int r2,s2,p2;

void save() {
    r1 = R1;s1 = S1;p1 = P1;
    r2 = R2;s2 = S2;p2 = P2;
}

void rec() {
    R1 = r1;S1 = s1;P1 = p1;
    R2 = r2;S2 = s2;P2 = p2;
}

int getS() {
    int ans = 0;
    //S
    num = min(S1,S2 + R2);
    S1 -= num;
    
    num2 = min(S2,num);
    S2 -= num2;
    num -= num2;
    
    num3 = min(R2,num);
    R2 -= num3;
    num -= num3;
    
    ans += S1;
    P2 -= S1;
    return ans;
}

int getR() {
    //R
    int ans = 0;
    num = min(R1,R2 + P2);
    R1 -= num;
    
    num2 = min(R2,num);
    R2 -= num2;
    num -= num2;
    
    num3 = min(P2,num);
    P2 -= num3;
    num -= num3;
    
    ans += R1;
    S2 -= R1;
    rec();
    return ans;
}

int getP() {
    //P;
    int ans = 0;
    num = min(P1,P2 + S2);
    P1 -= num;
    
    num2 = min(P2,num);
    P2 -= num2;
    num -= num2;
    
    num3 = min(S2,num);
    num -= num3;
    S2 -= num3;
    
    ans += P1;
    R2 -= P1;
    return ans;
}

int getWin() {
    int ans = 0;
    
    num = min(S1,P2);
    ans += num;
    S1 -= num;
    P2 -= num;
    
    num = min(R1,S2);
    ans += num;
    R1 -= num;
    S2 -= num;
    
    num = min(P1,R2);
    ans += num;
    P1 -= num;
    R2 -= num;
    
    return ans;
}



int main() {
    int n;scanf("%d",&n);
    scanf("%d%d%d",&R1,&S1,&P1);
    scanf("%d%d%d",&R2,&S2,&P2);
    
    
    int mi = 1e9,mx = 0;
    save();
    mi = min(mi,getR() + getS() + getP());
    rec();
    
    save();
    mi = min(mi,getR() + getP() + getS());
    rec();
    
    save();
    mi = min(mi,getS() + getP() + getR());
    rec();
    
    save();
    mi = min(mi,getS() + getR() + getP());
    rec();
    
    save();
    mi = min(mi,getP() + getR() + getS());
    rec();
    
    save();
    mi = min(mi,getP() + getS() + getR());
    rec();

    mx = getWin();
    printf("%d %d\n",mi,mx);
    return 0;
}
 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值