被 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 单独出一篇题解,就不放这里咯~。
标签:Educational,return,int,res,begin,vp,while,139,define From: https://www.cnblogs.com/ktqcpp/p/17021679.html