AtCoder Beginner Contest 386 赛后总结

赛时 A-D。菜。

A - C

模拟即可。

D

先检查一下竖着的一列有没有出现:白黑 或者 黑白黑 的情况。有的话一定不行。

因为每个白点的右下角一定都得是白的,就相当于对下面的行数取后缀最小值,这个可以使用差分实现。

点击查看代码
#include<bits/stdc++.h>

#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050

int n,m;
int x[maxn],y[maxn];
char ch[maxn];
int b[maxn<<1];
vector<pair<int,int> > G1[maxn<<1],G2[maxn<<1];
int fnt[maxn<<1];
void work() {
	cin>>n>>m;
	For(i,1,m) {
		cin>>x[i]>>y[i]>>ch[i];
		b[(i<<1)-1]=x[i];
		b[i<<1]=y[i];
	}
	sort(b+1,b+m+m+1);
	int len=unique(b+1,b+m+m+1)-b-1;
	For(i,1,m) {
		x[i]=lower_bound(b+1,b+len+1,x[i])-b;
		y[i]=lower_bound(b+1,b+len+1,y[i])-b;
		G1[x[i]].push_back({y[i],ch[i]=='W'});
		G2[y[i]].push_back({x[i],ch[i]=='W'});
	}
	For(i,1,len) {
		if(G1[i].size()<2) continue;
		sort(G1[i].begin(),G1[i].end());
		bool flg=0;
		int sz=G1[i].size()-1;
		For(j,0,sz) {
			if(G1[i][j].scd!=flg) {
				if(!flg) flg=1;
				else return cout<<"No",void();
			}
		}
	}
	For(i,0,len) fnt[i]=len+1;
	For(i,1,m) {
		if(ch[i]=='B') continue;
		fnt[x[i]]=min(y[i],fnt[x[i]]);
	}
	For(i,1,len) {
		fnt[i]=min(fnt[i-1],fnt[i]);
	}
	For(i,1,m) {
		if(ch[i]=='B'&&fnt[x[i]]<=y[i]) return cout<<"No",void();
	}
	cout<<"Yes";
}

signed main() {
	ios::sync_with_stdio(false); 
	cin.tie(0); cout.tie(0);
	int _=1;
//	_=read();
	For(i,1,_) {
		work();
	}
	return 0;
}

E

幽默搜索题。

你是一名 OIer。这天,你在和 abc 鏖战。
你开到了 E。你发现 (NK)106,这很像搜索。
你兴致冲冲的开始打搜索,想着 abc 怎么又出搜索题。
你交了上去,却得到了一群 TLE。
你突然发现,你的 dfs 被调用了 i=1k(Ni) 次,而当 kN2 时,dfs 时间复杂度巨大。
你发现 可逆,于是你打算在 k>N2 时反向搜索。
你打完了代码,交了上去,AC 了。

点击查看代码
#include<bits/stdc++.h>
#define int ll
#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050
int n,k;
int a[maxn];
int ans=0;
map<int,bool >vis;
void dfs(int u,int dep,int res) {
	if(dep==(k>n/2?n-k:k)) return ans=max(ans,res),void();
	if(u>n) return void();
	if((k<=n/2&&!vis[a[u]])||(k>n/2&&vis[a[u]])) 
		vis[a[u]]^=1,dfs(u+1,dep+1,res^a[u]),vis[a[u]]^=1;
	dfs(u+1,dep,res);
}
void work() {
	in2(n,k);
	int tmp=0;
	For(i,1,n) {
		in1(a[i]);
		if(k>n/2) {
			if(!vis[a[i]]) tmp^=a[i];
			vis[a[i]]=1; 
		}
	}
	dfs(1,0,k>n/2?tmp:0);
	cout<<ans;
}

signed main() {
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	int _=1;
//	_=read();
	For(i,1,_) {
		work();
	}
	return 0;
}
/*
4 3
3 2 6 4
*/

你笑了出来,感觉这一场又可以上大分了。
笑着笑着,梦醒了。
你发现你其实根本没做出来 E,这只是你上课睡觉时的幻想罢了。

F

编辑字符串。

有一个很典的方法,就是设 fi,j 表示 S1 串匹配到第 i 位,S2 串匹配到第 j 位,那么转移有 fi,j=min(fi1,j+1,fi,j1+1,fi1,j1+[S1iS2j])

因为 k20,所以我们只用考虑 ij 的间隔不超过 k 的情况,因为此时的最佳情况就是一直添加字符。

点击查看代码
#include<bits/stdc++.h>

#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 500050

int k,n,m;
string s1,s2;
int f[2][maxn];

void work() {
	cin>>k>>s1>>s2;
	n=s1.size(); s1=" "+s1;
	m=s2.size(); s2=" "+s2;
	mem(f,0x3f);
	f[0][0]=0;
	For(i,0,n) For(del,-21,21) {
		if(i+del<0||i+del>m) continue;
		int j=i+del;
		if(j==0) f[i&1][j]=i;
		else f[i&1][j]=min(min(f[(i-1)&1][j]+1,f[i&1][j-1]+1),f[(i-1)&1][j-1]+(s1[i]!=s2[j]));
	}
	cout<<(f[n&1][m]<=k?"Yes":"No");
}

signed main() {
	ios::sync_with_stdio(false); 
	cin.tie(0); cout.tie(0);
	int _=1;
//	_=read();
	For(i,1,_) {
		work();
	}
	return 0;
}
posted @   coding_goat_qwq  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示