2023杭电多校第二场 - 1 2 9
比赛地址:传送门
这回过了三个题,后面4个小时都在坐牢~
1001 博弈
1002 贪心
1009 读懂题意就会了
1001 Alice Game
题意
Alice 和 Bob 在玩一个游戏。有 n 个怪物站成一排。Alice and Bob 轮流进行操作,每次操作有两个选择:
- 选择一个连续的怪物序列,怪物数量需要小于等于 k ,玩家可以摧毁这一怪物序列
- 在一个连续的怪物序列里选择 k 个连续的怪物并且摧毁它们,要求摧毁之后,原怪物序列被划分为两个非空的左右序列,这两个序列视为不连通
规定哪位选手不能进行操作,则认定为输。问你 Alice 先进行操作,最后谁会赢得比赛?
思路
由题可知sg(0) = 0,sg(1 ~ k) = 1,sg(k + 1) = 0
利用 sg 函数分析问题,打表可得周期为 4k + 2
故每个周期的 k + 1 的位置和最初的 0 的位置均是必败态,其余均为必胜态
代码
//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x,y,sizeof(x))
#define debug(x) cout << #x << " = " << x << endl
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << endl
//#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ull,ull> pull;
typedef pair<double,double> pdd;
/*
*/
const int maxm = 2e5+5, inf = 0x3f3f3f3f, mod = 998244353;
void solve(){
int n, k;
cin >> k >> n;
if(n == 0 || n % (k * 4 + 2) == k + 1) cout << "Bob\n";
else cout << "Alice\n";
return ;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
cin >> _;
while(_--){
solve();
}
return 0;
}
打表代码:
//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x,y,sizeof(x))
#define debug(x) cout << #x << " = " << x << endl
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << endl
//#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ull,ull> pull;
typedef pair<double,double> pdd;
/*
*/
const int maxm = 2e5+5, inf = 0x3f3f3f3f, mod = 998244353;
int n = 1e2+5 , k = 3;
vector<int> sg(maxm + 5, 0);
int mex(int x){
set<int> q;
for(int i = 1; i <= x - k - 1; ++i){
q.insert(sg[i] ^ sg[x - k - i]);
}
int ans = 0;
while(q.find(ans) != q.end()){
++ ans;
}
return ans;
}
void solve(){
debug(k);
sg[0] = 0;
for(int i = 1; i <= k; ++i){
sg[i] = 1;
}
for(int i = k + 1; i <= n; ++i){
sg[i] = mex(i);
}
for(int i = 0; i <= n; ++i){
cout << sg[i] <<" \n"[i % (k * 4 + 2) == 0];
}
return ;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
// cin >> _;
while(_--){
solve();
}
return 0;
}
1002 Binary Number
题意:
给你一个 0-1 串长为 n 以及操作次数 k,每次操作可以选择一段区间\([l, r],(0\le l\le r\le n-1)\)使得该区间内字符 01 翻转,问你所能得到的最大的二进制字符串
思路:
首先我们可以知道,要想得到最大的二进制串,首先对于所有的操作一定是从前往后将连续的 0 翻成 1 ,这样最大;如果跨越 1 翻转反而得不偿失。如果说翻转之后 k 仍有剩余,我们则需判断其是否为 单字符串,即 n=1 的情况,若 n=1,则奇数次操作结果为 '0',偶数次操作结果为 '1';其他情况,我们可以知道,当剩下的操作次数为 '1' 时,将最后一位字符翻为 0即可,其他情况我们都可以将其操作为全 '1' 串,偶数次操作就不说了,奇数次操作可以操作时浪费一次操作多将一个'1' 变为 '0',之后翻转时少转这一位,最后再翻转其即可消去奇数多一次的影响
代码:
//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x,y,sizeof(x))
#define debug(x) cout << #x << " = " << x << endl
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << endl
//#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ull,ull> pull;
typedef pair<double,double> pdd;
/*
*/
const int maxm = 2e5+5, inf = 0x3f3f3f3f, mod = 998244353;
void solve(){
ll n, k;
string ss;
cin >> n >> k >> ss;
int q = k;
bool f = false;
for(int i = 0; i < n; ++ i){
if(ss[i] == '1'){
if(f){
f = false;
}
}else{
if(f) ss[i] = '1';
else if(q){
-- q;
ss[i] = '1';
f = true;
}
}
}
if(q){
if(n == 1){
if(q & 1) ss[n - 1] = '0';
}else if(k == q){
if(q == 1) ss[n - 1] = '0';
}
}
cout << ss <<'\n';
return ;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
cin >> _;
while(_--){
solve();
}
return 0;
}
1009 String Problem
题意:
给你一个字符串,让你找成对不相交的子串,每个子串仅由一个字符组成,其对于答案的贡献为 子串长度 - 1,问你最大化贡献。
思路:
就是判断是否有相邻位均为同一字符串,如果则 ++ ans,最后输出答案。
极其简单
代码:
//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x,y,sizeof(x))
#define debug(x) cout << #x << " = " << x << endl
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << endl
//#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ull,ull> pull;
typedef pair<double,double> pdd;
/*
*/
const int maxm = 2e5+5, inf = 0x3f3f3f3f, mod = 998244353;
void solve(){
string ss;
cin >> ss;
int len = ss.size(), ans = 0;
for(int i = 1; i < ss.size(); ++ i){
if(ss[i] == ss[i - 1]) ++ ans;
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
cin >> _;
while(_--){
solve();
}
return 0;
}
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17569411.html