A. Wallet Exchange
- 博弈
每人每次可移除任意钱包里的一枚硬币,不能移除的玩家失败,Alice先手,硬币数量a+b为奇数则Alice获胜,否则Bob获胜。
AC代码
#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
long long read(){
long long x=0,w=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')w=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<1)+(x<<3)+(c&15);
c=getchar();
}
return x*w;
}
int main(){
int t=read();
while(t--){
int a=read(),b=read();
if((a+b)&1)cout<<"Alice\n";
else cout<<"Bob\n";
}
}
B. Plus-Minus Split
- 贪心
+ 1 +1 +1和 − 1 -1 −1可以抵消,剩下的 + 1 +1 +1或 − 1 -1 −1划分成长度为 1 1 1的若干数组,使得数组总和 s u m sum sum以及数组长度 m m m最小,得到每个数组的最小值,各个最小值相加得到最终答案的最小值。
AC代码
#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
long long read(){
long long x=0,w=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')w=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<1)+(x<<3)+(c&15);
c=getchar();
}
return x*w;
}
int main(){
int t=read();
while(t--){
int n=read();
string s;cin>>s;
int zero=0,one=0;
for(char c:s){
if(c=='-')++zero;
else ++one;
}
cout<<abs(one-zero)<<endl;
}
}
C. Grouping Increases
- 贪心
将数组分为两个子序列,使得连续上升序列数总和最小。
将数组分为
b
b
b、
c
c
c数组,用
x
x
x、
y
y
y分别表示数组最后一个元素,并规定
x
≤
y
x \leq y
x≤y。
- a i ≤ x a_i \leq x ai≤x, a i a_i ai无论加入到 b b b或者 c c c数组,惩罚值 p e n a l t y penalty penalty都不会增加,将其加入进较小元素的数组中,以保留较大的元素。
- y < a i y < a_i y<ai, a i a_i ai无论加入到 b b b或者 c c c数组, p e n a l t y penalty penalty都会增加 1 1 1,将其加入进较小元素的数组中,以保留较大的元素。
- x < a i ≤ y x < a_i \leq y x<ai≤y, a i a_i ai加入 x x x所在数组会使 p e n a l t y penalty penalty增加 1 1 1,而加入 y y y所在的数组 p e n a l t y penalty penalty不会增加,故将其加入较大元素的数组中,以避免 p e n a l t y penalty penalty的增加。第一种情况与第二种情况保留较大元素正是为了此刻的较大元素 y ≥ a i y ≥ a_i y≥ai的可能性更大,降低 y < a i y < a_i y<ai导致 p e n a l t y penalty penalty必须增加的可能性,故此刻应该发挥较大元素 y y y的作用避免 p e n a l t y penalty penalty的增加。
AC代码
#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
long long read(){
long long x=0,w=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')w=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<1)+(x<<3)+(c&15);
c=getchar();
}
return x*w;
}
int main(){
int t=read();
while(t--){
int n=read();
int a;
int min1=INT32_MAX,min2=INT32_MAX;
int ans=0;
for(int i=0;i<n;++i){
a=read();
if(min1>min2)swap(min1,min2);
if(a<=min1)min1=a;
else if(min2<a){
min1=a;
++ans;
}
else min2=a;
}
cout<<ans<<endl;
}
}