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;
    }
    
  • 相关阅读:
    Mahout推荐算法ItemBased
    ALSA安装编程指南
    windbg更改cmd的token提升其特权
    至尊问题
    什么是“Bash”破绽?
    hdu 1548 A strange lift
    C 循环链表
    C++ 链表
    C_数据结构_链表的链式实现
    C _数据结构 _线性表的顺序存储
  • 原文地址:https://www.cnblogs.com/axiomofchoice/p/13375274.html
Copyright © 2011-2022 走看看