[Codeforces] games (R1200) Part.3

[Codeforces] games (R1200) Part.3

题单:https://codeforces.com/problemset?tags=games,0-1200

1672A. Log Chopping

原题指路:https://codeforces.com/problemset/problem/1672/A

题意

有编号 1 ∼ n 1\sim n 1n n n n段木头,其中第 i    ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i  (1in)段的长度为正整数 a i a_i ai.errorgorn和maomao90玩游戏,errorgorn先手.每轮每人选一段长度 ≥ 2 \geq 2 2的木头,将其锯成两段长度为 ≥ 1 \geq 1 1的正整数的木头,无法操作者负.两人都采取最优策略,问最后谁胜.

t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 50 ) n\ \ (1\leq n\leq 50) n  (1n50).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 50 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 50) a1,,an  (1ai50).

思路

游戏终止局面为有 ∑ i = 1 n a i \displaystyle\sum_{i=1}^n a_i i=1nai段长度为 1 1 1的木头.注意到长度为 a i a_i ai的木头无论怎么切都需切 ( a i − 1 ) (a_i-1) (ai1)次才能达到终止状态,故共有 ∑ i = 1 n ( a i − 1 ) = ∑ i = 1 n a i − n \displaystyle\sum_{i=1}^n (a_i-1)=\sum_{i=1}^n a_i-n i=1n(ai1)=i=1nain轮,判断其奇偶性即可.

代码

void solve() {
  int n; cin >> n;
  valarray<int> a(n);
  for (auto& ai : a) cin >> ai;

  cout << ((a.sum() - n & 1) ? "errorgorn" : "maomao90") << endl;
}

int main() {
  CaseT  // 单测时注释掉该行
    solve();
}


1673A. Subtle Substring Subtraction

原题指路:https://codeforces.com/problemset/problem/1673/A

题意

Alice和Bob玩游戏,Alice先手.初始时给定一个字符串 s s s,每人每轮可取走 s s s的一个子串,轮到Alice时,她可取走长度为偶数(包含 0 0 0)的子串;轮到Bob时,他可取走长度为奇数的子串.当 s s s为空串时游戏结束,计算各自的得分,分数高者获胜.每个人的得分为自己取走的字符串中各字符的个数的加权和,其中 a a a的权值为 1 1 1, b b b的权值为 2 , ⋯   , z 2,\cdots,z 2,,z的权值为 26 26 26.问最后谁胜,并求出胜者与负者的分数差.可以证明不会出现平局.

t    ( 1 ≤ t ≤ 5 e 4 ) t\ \ (1\leq t\leq 5\mathrm{e}4) t  (1t5e4)组测试数据.每组测试数据输入一个长度不超过 2 e 5 2\mathrm{e}5 2e5且只包含小写英文字母的字符串 s s s.数据保证所有测试数据的 s s s之和不超过 5 e 4 5\mathrm{e}4 5e4.

思路

(1) ∣ s ∣ = 1 |s|=1 s=1时,第一轮Alice只能取 0 0 0个字符,Bob胜.

(2) ∣ s ∣ |s| s为偶数时,Alice第一步取走整个字符串,Alice胜.

(3) ∣ s ∣ |s| s为奇数时,Alice的最优策略是取走长度为 ( ∣ s ∣ − 1 ) (|s|-1) (s1)的前缀或后缀,取决于 s [ 1 ] s[1] s[1](下标从 1 1 1开始)与 s [ ∣ s ∣ ] s[|s|] s[s]的权值的大小关系.

​ 下证Alice必胜.若不然,不妨设Alice取走长度为 ( ∣ s ∣ − 1 ) (|s|-1) (s1)的前缀,其权值之和为 a a a;Bob取走 s [ ∣ s ∣ ] s[|s|] s[s],其权值为 b b b.

​ 因 a < b a<b a<b,则 s [ 1 ] s[1] s[1]的权值 < b <b <b,按贪心策略,Alice应取长度为 ( ∣ s ∣ − 1 ) (|s|-1) (s1)的后缀,矛盾.

代码

void solve() {
  string s; cin >> s;

  int n = s.length();
  int sum = 0;  // 总分
  for (int i = 0; i < n; i++) sum += s[i] - 'a' + 1;

  if (n % 2 == 0) {
    cout << "Alice" << ' ' << sum << endl;
    return;
  }

  int bob = min(s[0], s[n - 1]) - 'a' + 1;
  if (n == 1) {
    cout << "Bob" << ' ' << bob << endl;
    return;
  }
  else cout << "Alice" << ' ' << sum - 2 * bob << endl;
}

int main() {
  CaseT  // 单测时注释掉该行
    solve();
}


1681A. Game with Cards

原题指路:https://codeforces.com/problemset/problem/1681/A

题意 ( 2   s 2\ \mathrm{s} 2 s)

Alice和Bob玩游戏.Alice有编号 1 ∼ n 1\sim n 1n n n n张牌,其中第 i    ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i  (1in)张牌上有数字 a i a_i ai;Bob有编号 1 ∼ m 1\sim m 1m m m m张牌,其中第 j    ( 1 ≤ j ≤ m ) j\ \ (1\leq j\leq m) j  (1jm)张牌上有数字 b j b_j bj.两人轮流出牌,后手出的牌上的数字要严格大于先手出的牌,无法操作者负.两人都采取最优策略,问Alice、Bob各自先手时谁胜.

t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\le 1000) t  (1t1000)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 50 ) n\ \ (1\leq n\leq 50) n  (1n50).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 50 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 50) a1,,an  (1ai50).第三行输入一个整数 m    ( 1 ≤ m ≤ 50 ) m\ \ (1\leq m\leq 50) m  (1m50).第四行输入 m m m个整数 b 1 , ⋯   , b m    ( 1 ≤ b i ≤ 50 ) b_1,\cdots,b_m\ \ (1\leq b_i\leq 50) b1,,bm  (1bi50).

思路

①若只有一张最大牌,则无论有最大牌的人是先手还是后手,他在第一轮或第二轮出都能获胜.

②若两人都有最大牌,显然先手必胜.

代码

void solve() {
  int n; cin >> n;
  valarray<int> a(n);
  for (auto& ai : a) cin >> ai;
  int m; cin >> m;
  valarray<int> b(m);
  for (auto& bi : b) cin >> bi;

  cout << (a.max() >= b.max() ? "Alice" : "Bob") << endl;
  cout << (a.max() > b.max() ? "Alice" : "Bob") << endl;
}

int main() {
  CaseT  // 单测时注释掉该行
    solve();
}


1684A. Digit Minimization

原题指路:https://codeforces.com/problemset/problem/1684/A

题意

给定正整数 n n n的不含前导零的十进制表示.A与B玩游戏,每轮A交换不同位置的数码,B删去最后一个数码,当 n n n只剩下要给数码时游戏结束.问A能得到的最小数.

t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入一个整数 n    ( 10 ≤ n ≤ 1 e 9 ) n\ \ (10\leq n\leq 1\mathrm{e}9) n  (10n1e9).

思路

①若 n n n只有 2 2 2个数码,则A只能得到末位的数.

②若 n n n至少有 3 3 3个数码,显然A可保留最小数码.

代码

void solve() {
  string s; cin >> s;
  cout << (s.length() == 2 ? s[1] : *min_element(all(s))) << endl;
}

int main() {
  CaseT  // 单测时注释掉该行
    solve();
}


1695A. Subrectangle Guess

原题指路:https://codeforces.com/problemset/problem/1695/A

题意

给定一个 n × m n\times m n×m的整型矩阵,其中元素两两相异.A与B玩游戏,A选定一个 h × w    ( 1 ≤ h ≤ n , 1 ≤ w ≤ m ) h\times w\ \ (1\leq h\leq n,1\leq w\leq m) h×w  (1hn,1wm)的矩形,B猜其中的最大值,猜对则B胜;否则A胜.为保证B胜, h × w h\times w h×w至少多大.

t    ( 1 ≤ t ≤ 20 ) t\ \ (1\leq t\leq 20) t  (1t20)组测试数据.每组测试数据输入两个整数 n , m    ( 1 ≤ n , m ≤ 40 ) n,m\ \ (1\leq n,m\leq 40) n,m  (1n,m40).接下来输入一个 n × m n\times m n×m的整型矩阵,其中元素范围为 [ − 1 e 9 , 1 e 9 ] [-1\mathrm{e}9,1\mathrm{e}9] [1e9,1e9]且两两相异.

思路

h × w h\times w h×w的矩形大到无论如何放置都能覆盖整个矩阵的最大值时B必胜.

代码

const int MAXN = 45;
int n, m;
int a[MAXN][MAXN];

void solve() {
  cin >> n >> m;
  int maxi = 1, maxj = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> a[i][j];
      if (a[i][j] > a[maxi][maxj]) maxi = i, maxj = j;
    }
  }

  int h = max(maxi, n - maxi + 1), w = max(maxj, m - maxj + 1);
  cout << h * w << endl;
}

int main() {
  CaseT  // 单测时注释掉该行
    solve();
}


1695B. Circle Game

原题指路:https://codeforces.com/problemset/problem/1695/B

题意

编号 1 ∼ n 1\sim n 1n n n n堆石头围成一圈,其中第 i    ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i  (1in)堆石头有 a i a_i ai个.Mike和Joe玩游戏,Mike先手.从第一堆石头开始,若当前玩家从第 i i i堆拿石头,则下一个玩家从第 ( i   m o d   n ) + 1 ) (i\ \mathrm{mod}\ n)+1) (i mod n)+1)堆拿石头.每轮每人从当前的堆拿任意数量的石头,可拿完,但不能不拿,无法操作者负.两人都采取最优策略,问谁胜.

t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 50 ) n\ \ (1\leq n\leq 50) n  (1n50).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}9) a1,,an  (1ai1e9).

思路

n n n为奇数时,Mike每次取完他的每一堆,则最后轮到Joe取空的第 1 1 1堆,故Mike胜.

n n n为偶数时,Mike和Joe各自取自己的 n 2 \dfrac{n}{2} 2n堆,则石头数最少的堆将先被取完,判断石头数最少的堆的编号的奇偶性即可,若有多个石头数最少的堆,取编号最小的.

代码

void solve() {
  int n; cin >> n;
  vi a(n);
  for (auto& ai : a) cin >> ai;

  if (n & 1) {
    cout << "Mike" << endl;
    return;
  }

  int minidx = 0;
  for (int i = 1; i < n; i++)
    if (a[i] < a[minidx]) minidx = i;
  cout << (minidx & 1 ? " Mike" : "Joe") << endl;
}

int main() {
  CaseT  // 单测时注释掉该行
    solve();
}


1719A. Chip Game

原题指路:https://codeforces.com/problemset/problem/1719/A

题意

给定一个 n × m n\times m n×m表格,初始时左下角有一个棋子.Burenka和Tonya玩游戏,Burenka先手.每轮每人可将棋子向上或向右移动奇数个格子,不能超出表格边界,不能移动者负.两人都采取最优策略,问最后谁胜.

t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入两个整数 n , m    ( 1 ≤ n , m ≤ 1 e 9 ) n,m\ \ (1\leq n,m\leq 1\mathrm{e}9) n,m  (1n,m1e9).

思路

注意到游戏结束当且仅当棋子在右上角,否则至少能做一次步长为 1 1 1的移动,故移动距离为 ( n − 1 ) + ( m − 1 ) = n + m − 2 (n-1)+(m-1)=n+m-2 (n1)+(m1)=n+m2.

因每次移动的步长都为奇数,则移动一次会改变剩余距离的奇偶性,故判断 ( n + m − 2 ) (n+m-2) (n+m2)的奇偶性即可.

代码

void solve() {
	int n, m; cin >> n >> m;
	if (n + m & 1) cout << "Burenka" << endl;
	else cout << "Tonya" << endl;
}
 
int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


截至2022.10.20,无新题目.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值