zoukankan      html  css  js  c++  java
  • 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 "
    "
    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
    ",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 "
    "
    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;
    }
    
  • 相关阅读:
    hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map
    hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
    hdu6438 Buy and Resell 买卖物品 ccpc网络赛 贪心
    hdu6441 Find Integer 求勾股数 费马大定理
    bzoj 1176 Mokia
    luogu 3415 祭坛
    bzoj 1010 玩具装箱
    bzoj 3312 No Change
    luogu 3383【模板】线性筛素数
    bzoj 1067 降雨量
  • 原文地址:https://www.cnblogs.com/axiomofchoice/p/13375274.html
Copyright © 2011-2022 走看看