Codeforces Round #685 (Div. 2)

这是一场考得很不好的比赛,逐一分析问题,下次找回面子(和(Rating))。

(A.quad Subtractquad orquad Divide)

第一眼感觉没有思路(也是我第一次(div_2)(A)题没思路),于是打了个100的表出来。

发现当(4leq n)时,偶数答案为2,奇数答案为3。

思考原因,发现若是偶数,则一次除成2再减1,若为奇数则先减成偶数。

正确性显然。考场代码如下:

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int maxn=2e5+10;
const int mod=1e9+7;
int T,n,dp[maxn];
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int main(){
	T=read();
	while(T--){
		n=read();
		if(n==1)puts("0");
		else if(n==2)puts("1");
		else if(n==3)puts("2");
		else if(n%2==0)puts("2");
		else puts("3");
	}
	return 0;
}

(B.quad Non-Substringquad Subsequence)

考虑改变串首和串尾的位置,若可以改变则可行,否则一定不可行。

考场代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int maxn=1e3+10;
const int mod=1e9+7;
int T,n,m,sum[maxn];
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int main(){
	T=read();
	while(T--){
		n=read(),m=read();
		string s;cin>>s;
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=n;i++)
			sum[i]=sum[i-1]+s[i-1]-'0';
		int l,r;
		for(int i=1;i<=m;i++){
			l=read(),r=read();
			if(s[l-1]=='0'&&sum[l-1]!=l-1)puts("YES");
			else if(s[l-1]=='1'&&sum[l-1])puts("YES");
			else if(s[r-1]=='0'&&sum[n]-sum[r]!=n-r)puts("YES");
			else if(s[r-1]=='1'&&sum[n]-sum[r])puts("YES");
			else puts("NO");
		}
	}
	return 0;
}

以上是我做出来了的,没错,只有两道,(rank)到了(5000^+)

重点分析以下没有做出来的/做错的题目:

(C.quad Stringquad Equality)

不考虑顺序。考场上我直接排了个序,但发现元素只有26个,可以桶排。

由于字母只能越变越大,则我们从前往后考虑。

如果对字母(alpha),若(b)中比(a)中多,则无论如何操作都无法将(a)中的(alpha)变多,故不行。

(a)中的部分(alpha)(b)中的抵掉后,需要将剩余的传到下一个,若剩余的不为(k)的倍数,也不行。

否则,则将(a)(alpha+1)加上剩余的,考虑下一个。

考后改题代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int maxn=2e5+10;
const int mod=1e9+7;
int T,n,m,a[maxn],b[maxn];
string A,B;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int main(){
	T=read();
	while(T--){
		n=read();m=read();
		cin>>A>>B;
		for(int i=0;i<26;i++)
			a[i]=b[i]=0;
		for(int i=0;i<n;i++)
			a[A[i]-'a']++,b[B[i]-'a']++;
		int flag=1;
		for(int i=0;i<26;i++){
			if(a[i]<b[i]){flag=0;break;}
			if((a[i]-b[i])%m){flag=0;break;}
			a[i+1]+=a[i]-b[i];
		}
		puts(flag?"Yes":"No");
	}
	return 0;
}

(D.quad Circlequad Game)

给出结论:找到最大的(ans)使((ans*k,ans*k))在圆内,若((ans*k,ans*k+k))也在圆内,则先手赢,否则后手赢。

证明:若((ans*k,ans*k+k))不在圆内则后手只需保持在(y=x)上即可。否则先手只需保持在(y=x-k)上即可。

很少做博弈论的题,以后注意找特殊的必胜策略。

考后改题代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+10;
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*f;
}
int T,d,k;
inline int check(int x,int y){
    return x*x+y*y<=d*d;
}
signed main(){
    T=read();
    while(T--){
        d=read(),k=read();
        int l=0,r=d/k+1,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid*k,mid*k))ans=mid,l=mid+1;
            else r=mid-1;
        }
        //printf("%lld
",ans);
        puts(check(ans*k,ans*k+k)?"Ashish":"Utkarsh");
    }
    return 0;
}

注意不要爆(long long)了。

(E1.quad Bitwisequad Queriesquad (Easyquad Version))

其实这道题我考场想出来正解了,然而由于不会写交互鸽了。

给出构造:发现只要五个式子就可以唯一确定三个数,即:({a|b,b|c,a&b,b&c,c&a} ightarrow{a,b,c})

原因是:(a+b=a&b+a|b)(a+b+c=a|b|c+a&b+b&c+c&a-a&b&c)

又有知道一个数与已知数的异或可以唯一确定这个数,故操作次数为(n+2)次。

改题代码如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6+10;
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*f;
}
int n,a[maxn],a12,a23,a13,o12,o23,sum;
signed main(){
    n=read();
    puts("AND 1 2");fflush(stdout);a12=read();
    puts("AND 2 3");fflush(stdout);a23=read();
    puts("AND 1 3");fflush(stdout);a13=read();
    puts("OR 1 2");fflush(stdout);o12=read();
    puts("OR 2 3");fflush(stdout);o23=read();
    sum=(o12|o23)+a12+a23+a13-(a12&a23);
    a[1]=sum-a23-o23;a[3]=sum-a12-o12;a[2]=sum-a[1]-a[3];
    for(int i=4;i<=n;i++){
        printf("XOR 1 %lld
",i);
        fflush(stdout);
        a[i]=read()^a[1];
    }
    printf("!");
    for(int i=1;i<=n;i++)
        printf(" %lld",a[i]);
    return 0;
}

收获:知道怎么做交互了??(大雾)

(E2.quad Bitwisequad Queriesquad (Hardquad Version))

(F.quad Nullifyquad Thequad Matrix)

原文地址:https://www.cnblogs.com/syzf2222/p/14018118.html