当前位置: 代码迷 >> 综合 >> 2020 CCPC-Wannafly Winter Camp Day6 Div.12——C.酒馆战棋【模拟】
  详细解决方案

2020 CCPC-Wannafly Winter Camp Day6 Div.12——C.酒馆战棋【模拟】

热度:24   发布时间:2023-12-16 22:53:55.0

题目传送门


题目描述

酒馆战棋是一个很有趣的游戏,这个游戏一共有两名玩家,每个玩家各自控制一定数量的随从,随从从左往右排列。
随从有两个基础属性:攻击力的血量,两个随从交战后会受到对方攻击力的伤害(失去对应的血量),当一个随从的血量降到 0 {0} 0 或者以下时会死亡。
整个对战流程如下:你的随从从左往右依次进行攻击,每次攻击是随机选择一个可以攻击的对方随从进行攻击。而对方的随从全程不动。
由于对方开了外挂,所以他的随从的血量和攻击力都是无穷大,而你的随从的攻击力和血量都是 1 {1} 1,但是随从除了攻击力和血量以外可能还有一些其他的属性:
圣盾:圣盾可以抵挡一次伤害,抵挡伤害后圣盾会消失。
剧毒:拥有剧毒属性的随从攻击力视为无穷大(由于你的随从的攻击力都是 1 {1} 1,所以只有剧毒属性才能击杀对方的随从)。
嘲讽:当对方场上有带有嘲讽的随从时,你只能攻击有嘲讽的随从。
现在已知你的随从从左往右分别有哪些属性,以及对方各种属性的随从有几个(显然对方随从的顺序并不会影响战斗)。
因为每次攻击是随机选择的,所以出题人经常被系统给演了,所以他想知道在所有情况下最多能消灭几只随从,以及最少能消灭几只随从。


输入描述:

第一行一个正整数 T {T} T 表示数据组数 ( 1 ≤ T ≤ 100 ) (1\leq T\leq 100) (1T100)
对于每组数据:
第一行五个整数 n , a , b , c , d {n,a,b,c,d} n,a,b,c,d,表示你的随从个数,以及对方的普通随从,圣盾随从,嘲讽随从,圣盾嘲讽随从的个数。(因为对方的随从的属性都是无限大,所以剧毒对他来说没有意义)
第二行一个长度为 n {n} n 01 {01} 01 串,第 i {i} i 个字符为 1 {1} 1 表示从左往右第 i {i} i 个随从是否具有剧毒属性,若有则为 1 {1} 1,否则为 0 {0} 0。(因为只需要关心消灭了几个随从,所以嘲讽和圣盾属性无意义)。
保证 1 ≤ n ≤ 1000 , 0 ≤ a , b , c , d ≤ 1000 1\leq n\leq 1000,0\leq a,b,c,d\leq 1000 1n10000a,b,c,d1000


输出描述:

对于每组数据输出一行两个整数,表示最多消灭几个随从以及最少消灭几个随从。


输入

1
5 2 2 2 1
10101

输出

3 2


题解

  • 最好情况:普通随从破盾,剧毒随从杀怪
  • 最坏情况:剧毒随从破盾
  • 模拟即可

AC-Code

#include <bits/stdc++.h>
using namespace std;string s;int kill_max(int a, int b, int c, int d){
    int ans = 0;for(int i = 0; i < s.length(); ++i){
    if(s[i] == '0'){
    if(d > 0)    --d,++c;else if(c > 0)    continue;else if(b > 0)    --b,++a;}else{
    if(c > 0)    --c,++ans;else if(d > 0)    --d,++c;else if(a > 0)    --a,++ans;else if(b > 0)    --b,++a;}}return ans;
}int kill_min(int a, int b, int c, int d){
    int ans = 0;for(int i = 0; i < s.length(); ++i){
    if(s[i] == '0'){
    if(c > 0)    continue;else if(d > 0)    --d,++c;else if(a > 0)    continue;else if(b > 0)    --b,++a;}else{
    if(d > 0)    --d,++c;else if(c > 0)    --c,++ans;else if(b > 0)    --b,++a;else if(a > 0)    --a,++ans;}}return ans;
}int main(){
    int T;    cin >> T;while(T--){
    int n,a,b,c,d;    cin >> n >> a >> b >> c >> d;cin >> s;cout << kill_max(a,b,c,d) << " " << kill_min(a,b,c,d) << endl;}
}