Educational Codeforces Round 139 vp记

返回目录

Jerry__Jiang 神 爆杀的一天

Educational Codeforces Round 139 vp记

Problem A

简单题,随便枚举下即可

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T,n;
void solve(){
	n=read();
	int ans=0;
	for(int j=1;j<=n;j*=10){
		for(int i=1;i<=9;i++){
			if(i*j<=n)ans++;
		}
	}
	out(ans);
	puts("");
	return;
}
signed main(){
	T=read();
	while(T--)solve();
	return 0;
}

Problem B

因为要严格小于次数 n,又字符串长度等于 n,我没看见这条件想了半天。就不难可以想出我们需要至少执行一次长度大于等于 2 的 copy,然后由小学知识可得,能够执行长度大于 2 的 copy 就一定能执行长度等于 2 的。然后就应该不难了吧。

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T;
int n;
char s[200005];
const int base=100;
unordered_map<int,int> mp;
void solve(){
	mp.clear();
	n=read();
	scanf("%s",s+1);
	rep(i,n-1){
		if(mp[(s[i]-'a'+1)*base+(s[i+1]-'a'+1)]){
			puts("YES");
			return;
		}
		mp[(s[i-1]-'a'+1)*base+(s[i]-'a'+1)]++;
	}
	puts("NO");
	return;
}
signed main(){
	T=read();
	while(T--)solve();
	return 0;
}

Problem C

这道题我们首先要发现一个性质:因为只有 2 行,我们一旦离开一个只有一个 'B' 的列就不可能再回来,也就是说,我们只需要关心最近的两个只有一个 'B' 的列能否互相到达。

不难想出,如果最近的两个只有一个 'B' 的列之间有偶数个有两个 'B' 的列的话,那这两列的 'B' 不能在同一行。反之必须在同一行。

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T,n;
char s[4][200005];
void solve(){
	n=read();
	rep(i,2){
		scanf("%s",s[i]+1);
	}
	if(n==1){
		puts("YES");
		return;
	}
	int lst=-1;
	rep(j,n){
		int res=0;
		rep(i,2){
			if(s[i][j]=='B')res++;
		}
		if(res==0){
			puts("NO");
			return;
		}
		if(res==1){
			if(lst==-1){
				lst=j;
			}
			else{
				if((j-lst)%2==1){
					if(s[1][lst]!=s[1][j]){
						puts("NO");
						return;
					}
				}
				else{
					if(s[1][lst]==s[1][j]){
						puts("NO");
						return;
					}
				}
				lst=j;
			}
		}
	}
	puts("YES");
	return;
}
signed main(){
	T=read();
	while(T--)solve();
	return 0;
}

Problem D

小学数学题,但是要卡常

在往下看前,请读者先细想一下,我们令答案为 answer ,那么 answer 会有什么性质。

首先,我们可以想出,会存在一个 A ,使得 \(\begin{cases}y+answer\equiv 0\pmod{A}\\x+answer\equiv 0\pmod{A}\end{cases}\)

然后就可以发现 A 满足一个性质:\(x \equiv y \pmod{A}\)\(\max{(x,y)}-\min{(x,y)}\equiv0\pmod{A}\) 所以我们可以枚举这个 A。

又由小学知识可得,这个 A 为质数时是最优答案,我们就可以去做了

Code
#include<bits/stdc++.h>
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int T,x,y;
bool vis[3165];
int cnt,pri[3165];
void init(){
	for(int i=2;i<=3163;i++){
		if(!vis[i])pri[++cnt]=i;
		rep(j,cnt){
			if(pri[j]*i>3163)break;
			vis[pri[j]*i]=1;
			if(i%pri[j]==0)break;
		}
	}
//	cout<<cnt<<endl;
	return;
}
signed main(){
	init();
	T=read();
	while(T--){
		x=read(),y=read();
		if(x>y)swap(x,y);
		int z=y-x,k=1e9;
		//x+k=0 mod pri[i]
		//y+k=0 mod pri[i]
		if(__gcd(x,y)!=1){
			puts("0");
			continue;
//			return;
		}
		for(int i=1;z!=1&&pri[i]<=z&&i<=cnt;i++){
			if(z%pri[i]==0){
				if(y%pri[i]==0){
					k=0;break;
				}
				else chkmin(k,pri[i]-y%pri[i]);
			}
			while(z%pri[i]==0){
				z=z/pri[i];
			}
		}
		if(z>1){
			if(y%z==0)k=0;
			else chkmin(k,z-y%z);
		}
		if(k==1e9)puts("-1");
		else printf("%d\n",k);
	}
	return 0;
}

Problem E

这道题首先不难看出一个性质,对于所有的 0 ,它肯定是自成一个子序列,且贡献为 \(i\times(n-i+1)\) (假设 0 的坐标为 i)。

那么对于剩下的序列,我们需要再看出一个性质:数字 3 必定放在序列一,且最多有 3 个序列。

然后就可以令 \(dp_{i,j,k,l}\) 为以第 \(i\) 个数为最后一个插入的数,第一个序列结尾为 \(j\),第二个序列结尾为 \(k\),第三个序列结尾为 \(l\) 的答案。

Code
#include<bits/stdc++.h>
#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
template <typename T>void die(T s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template <typename T>void chkmax(T& a,T b){if(a<b)a=b;return;}
template <typename T>void chkmin(T& a,T b){if(a>b)a=b;return;}
int n;
int a[300005],ans,dp[300005][4][4][4];
int lst;
signed main(){
	n=read();
	rep(i,n)a[i]=read();
	rep(i,n){
		dp[lst][0][0][0]++;
		if(a[i]==0){
			ans=ans+i*(n-i+1);
		}
		else{
			for(int j=0;j<=3;j++){
				for(int k=0;k<=3;k++){
					for(int l=0;l<=3;l++){
						if(j==0||(j&a[i])!=0){
							dp[i][a[i]][k][l]+=dp[lst][j][k][l];
						}
						else if(k==0||(k&a[i])!=0){
							dp[i][j][a[i]][l]+=dp[lst][j][k][l];
						}
						else{
							dp[i][j][k][a[i]]+=dp[lst][j][k][l];
						}
					}
				}
			}
			lst=i;
		}
		repe(j,0,3){
			repe(k,0,3){
				repe(l,0,3){
					ans=ans+dp[lst][j][k][l]*((j>0? 1:0)+(k>0? 1:0)+(l>0? 1:0));
				}
			}
		}
	}
	out(ans);
	return 0;
}

完结撒花~

后面可能会对 F 单独出一篇题解,就不放这里咯~。

posted @ 2023-01-03 12:03  ktq_cpp  阅读(38)  评论(0)    收藏  举报