题目链接:hdu 7548 SunBian (2024“钉耙编程”中国大学生算法设计超级联赛(10))
思路:
一道比较签到的题。
先说结论:
1.当n=k时A必胜
2.当k=1时,n为奇数A胜,否则B胜
3.其余情况全都为B胜
证明:
1.显然n=k时A可以一回合全部取完
2.k=1时双方只能轮流来,显然奇数A胜偶数B胜
3.此时A是无法一回合全部取完的,且A无论如何操作都会使环形的笋变成一条链
那么B此时需要进行的操作就是取中间的笋(若为奇数取中间一个,反之取中间两个),将整个链分成两部分,然后镜像对手的操作,即可保证必胜。(有点类似Nim石子游戏 只有两堆且两堆相同的情况,后手必胜)
举个例子:
n=8 k=2时
可以看到,无论A取一个还是两个节点,都会使得整个环形被变成一条链,这里以取一个节点为例:
此时剩余7个节点,B可以取第四个节点让整个图形变成两条相同的链,如图
此时若A取其中的某一个或者某两个连续的节点,B可以在另一条链上镜像对手的操作,如图(红色代表A的操作,绿色代表B的操作)
此时A只能在剩下两个节点里面任选一个了,而后B选另一个就可以保证B必胜。
如果A第一步选了两个节点,剩下一条长度为6的链,则B可以选择第3、4节点,让原图变成两条长度为2的链,显然仍然是B胜
代码:
#include <iostream>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <set>
#include <map>
#include <stack>
#include <iomanip>
#include <numeric>
#include <cmath>
#include <functional>
#include <numeric>
#include <ctime>
#include <random>
#include <queue>
#include <vector>
#include <unordered_map>
#define sqr(x) ((x) * (x))
#define fo(x) for(int i=0;i<x;i++)
#define _for(a,b,c) for(int a=b;a<c;a++)
#define _rep(a,b,c) for(int a=b;a<=c;a++)
#define ll long long
#define inf 0x3f3f3f3f
#define endl '\n'
#define ull unsigned long long
#define int long long
#define MAXN 1000005
#define MAXM 26
#define mod 998244353
using namespace std;
void solve() {
int n, k;
cin >> n >> k;
if (n == k) {
cout << 'A';
return;
}
if (k == 1) {
if (n % 2 == 0) {
cout << 'B';
}
else {
cout << 'A';
}
return;
}
cout << 'B';
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(0);
int t = 1;
cin >> t;
while (t--) {
solve();
}
}
标签:hdu,cout,int,SunBian,cin,7548,必胜,include,节点
From: https://blog.csdn.net/sgss222/article/details/141650144