Codeforces Round #659 (Div. 1) 题解 (AB)

水个题解压压惊

A. String Transformation 1

贪心就好了。每次选择所有A里最小的、需要改变的字符,然后改变成最小的对应B值,差不多这个意思吧(?)

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii;
const int mod=(1?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
//#define int ll
int a[20][20];
char A[N],B[N];
void Solve(){
	int n=read();
	scanf("%s%s",A,B); mst(a,0);
	repeat(i,0,n){
		if(A[i]>B[i]){
			puts("-1");
			return;
		}
		a[A[i]-'a'][B[i]-'a']++;
	}
	n=20; int ans=0;
	repeat(i,0,n-1){
		int t=inf;
		repeat(j,i+1,n)
		if(a[i][j]){
			t=min(t,j);
		}
		if(t!=inf){
			ans++;
			repeat(j,i+1,n)
				a[t][j]+=a[i][j];
		}
	}
	printf("%d\n",ans);
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}

B. GameGame

大意:n个数,两人轮流选,选完为止,谁选的数字异或和最大谁就获胜,问先手必胜/和局/必败?

首先设s为所有数的异或和。如果s是0,那么不管怎么选,两人分数一定相同,就和局。如果不和局的话,两人的获胜关键就是s的最高位(二进制)。谁拿走了奇数个含有s最高位的数,谁就获胜(因为对面一定拿了偶数个)

我们令cnt1为含有s最高位的数的个数,cnt0为n-cnt1,接下来分情况讨论

  • 如果 \(cnt1\%4==1\),那么必胜,策略是先拿一个cnt1,然后看后手操作,如果后手拿cnt1,你也拿cnt1,后手拿cnt0你也拿cnt0(如果有的话)。这样保证你一定能拿奇数个cnt1。
  • 如果 \(cnt1\%4==3\)\(n\%2==0\),那么必胜,策略是先拿一个cnt0,然后操作同第一种情况。因为后手拿最后一个数,这样操作保证后手拿最后一个cnt1
  • 如果 \(cnt1\%4==3\)\(n\%2!=0\),那么必败。因为先手一定拿最后一个数,后手只要模仿先手操作(同前两种情况),就能获胜
#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define fi first
#define se second
#define endl "\n"
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
//mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int N=200010; typedef long long ll; const int inf=~0u>>2; const ll INF=~0ull>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;} typedef double lf; const lf pi=acos(-1.0); lf readf(){lf x; if(scanf("%lf",&x)==-1)exit(0); return x;} typedef pair<ll,ll> pii;
const int mod=(1?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;}
//#define int ll
int a[N],cnt[2];
void Solve(){
	int n=read(),s=0;
	repeat(i,0,n){
		a[i]=read();
		s^=a[i];
	}
	if(s==0){puts("DRAW"); return;}
	int b=1<<(31-__builtin_clz(s)); //orz(b);
	mst(cnt,0);
	repeat(i,0,n)cnt[bool(a[i]&b)]++;
	if(cnt[1]%4==1 || n%2==0)puts("WIN");
	else puts("LOSE");
}
signed main(){
	int T=1; T=read();
	while(T--)Solve();
	return 0;
}
posted @ 2020-07-25 00:43  axiomofchoice  阅读(319)  评论(0编辑  收藏  举报