[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 1∼n的 n n n段木头,其中第 i ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i (1≤i≤n)段的长度为正整数 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 (1≤t≤100)组测试数据.每组测试数据第一行输入一个整数 n ( 1 ≤ n ≤ 50 ) n\ \ (1\leq n\leq 50) n (1≤n≤50).第二行输入 n n n个整数 a 1 , ⋯ , a n ( 1 ≤ a i ≤ 50 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 50) a1,⋯,an (1≤ai≤50).
思路
游戏终止局面为有 ∑ i = 1 n a i \displaystyle\sum_{i=1}^n a_i i=1∑nai段长度为 1 1 1的木头.注意到长度为 a i a_i ai的木头无论怎么切都需切 ( a i − 1 ) (a_i-1) (ai−1)次才能达到终止状态,故共有 ∑ 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=1∑n(ai−1)=i=1∑nai−n轮,判断其奇偶性即可.
代码
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 (1≤t≤5e4)组测试数据.每组测试数据输入一个长度不超过 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) (∣s∣−1)的前缀或后缀,取决于 s [ 1 ] s[1] s[1](下标从 1 1 1开始)与 s [ ∣ s ∣ ] s[|s|] s[∣s∣]的权值的大小关系.
下证Alice必胜.若不然,不妨设Alice取走长度为 ( ∣ s ∣ − 1 ) (|s|-1) (∣s∣−1)的前缀,其权值之和为 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) (∣s∣−1)的后缀,矛盾.
代码
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 1∼n的 n n n张牌,其中第 i ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i (1≤i≤n)张牌上有数字 a i a_i ai;Bob有编号 1 ∼ m 1\sim m 1∼m的 m m m张牌,其中第 j ( 1 ≤ j ≤ m ) j\ \ (1\leq j\leq m) j (1≤j≤m)张牌上有数字 b j b_j bj.两人轮流出牌,后手出的牌上的数字要严格大于先手出的牌,无法操作者负.两人都采取最优策略,问Alice、Bob各自先手时谁胜.
有 t ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\le 1000) t (1≤t≤1000)组测试数据.每组测试数据第一行输入一个整数 n ( 1 ≤ n ≤ 50 ) n\ \ (1\leq n\leq 50) n (1≤n≤50).第二行输入 n n n个整数 a 1 , ⋯ , a n ( 1 ≤ a i ≤ 50 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 50) a1,⋯,an (1≤ai≤50).第三行输入一个整数 m ( 1 ≤ m ≤ 50 ) m\ \ (1\leq m\leq 50) m (1≤m≤50).第四行输入 m m m个整数 b 1 , ⋯ , b m ( 1 ≤ b i ≤ 50 ) b_1,\cdots,b_m\ \ (1\leq b_i\leq 50) b1,⋯,bm (1≤bi≤50).
思路
①若只有一张最大牌,则无论有最大牌的人是先手还是后手,他在第一轮或第二轮出都能获胜.
②若两人都有最大牌,显然先手必胜.
代码
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 (1≤t≤1e4)组测试数据.每组测试数据输入一个整数 n ( 10 ≤ n ≤ 1 e 9 ) n\ \ (10\leq n\leq 1\mathrm{e}9) n (10≤n≤1e9).
思路
①若 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 (1≤h≤n,1≤w≤m)的矩形,B猜其中的最大值,猜对则B胜;否则A胜.为保证B胜, h × w h\times w h×w至少多大.
有 t ( 1 ≤ t ≤ 20 ) t\ \ (1\leq t\leq 20) t (1≤t≤20)组测试数据.每组测试数据输入两个整数 n , m ( 1 ≤ n , m ≤ 40 ) n,m\ \ (1\leq n,m\leq 40) n,m (1≤n,m≤40).接下来输入一个 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 1∼n的 n n n堆石头围成一圈,其中第 i ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i (1≤i≤n)堆石头有 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 (1≤t≤1000)组测试数据.每组测试数据第一行输入一个整数 n ( 1 ≤ n ≤ 50 ) n\ \ (1\leq n\leq 50) n (1≤n≤50).第二行输入 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 (1≤ai≤1e9).
思路
① 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 (1≤t≤1e4)组测试数据.每组测试数据输入两个整数 n , m ( 1 ≤ n , m ≤ 1 e 9 ) n,m\ \ (1\leq n,m\leq 1\mathrm{e}9) n,m (1≤n,m≤1e9).
思路
注意到游戏结束当且仅当棋子在右上角,否则至少能做一次步长为 1 1 1的移动,故移动距离为 ( n − 1 ) + ( m − 1 ) = n + m − 2 (n-1)+(m-1)=n+m-2 (n−1)+(m−1)=n+m−2.
因每次移动的步长都为奇数,则移动一次会改变剩余距离的奇偶性,故判断 ( n + m − 2 ) (n+m-2) (n+m−2)的奇偶性即可.
代码
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,无新题目.