Codeforces Round 933 (Div. 3) (C-G)

这场比赛由于急躁心态不稳导致abc三题接连wa,这时候心态几乎爆炸。而d题思路其实很清晰,但是因为set使用不熟练卡住。最后没用set十分钟就写完过了。这时候只剩下十多分钟来不及写别的了。结束

收获主要就是:还是要注意边界的细节(

ab题就不放了。。

C - Rudolf and the Ugly String

这题具体是个什么咱也不知道。反正就是字符串匹配。就是没有什么算法硬做,只有三种情况

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+5;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
	return x*f;
}
int a[maxn];
signed main()
{
//	int t=read();
	int t;
	cin>>t;
	while(t--){
		int n;
		string s;
		cin>>n>>s;
		int j=0;
		int k=0;
		int ans=0;
		for(int i=0;i<n;i++){
			if(!j&&s[i]=='m'){
				k=0;
				j++;
			}
			else if(j==1&&s[i]=='a'){
				k=0;j++;
			}
			else if(j==2&&s[i]=='p'){
				j=0;k=0;ans++;
			}
			else if(!k&&s[i]=='p'){
				j=0;k++;
			}
			else if(k==1&&s[i]=='i'){
				j=0;k++;
			}
			else if(k==2&&s[i]=='e'){
				k=0;ans++;
			}
		}
		cout<<ans<<endl;
	}
}

D - Rudolf and the Ball Game

这题只有前一个状态和现在的状态有用,本来用set想去重的,但是直接替换成遍历用01表示了(因为n不是很大可以每次都遍历

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e3+5;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
	return x*f;
}
int a[maxn][2];
signed main()
{
	int t,n,m,x,dis;
	cin>>t;
	while(t--){
		cin>>n>>m>>x;
		for(int i=1;i<=n;i++){
			a[i][0]=0;
			a[i][1]=0;
		}
		int pos=0;
		a[x][0]=1;
		for(int i=1;i<=m;i++){
			pos=pos^1;
			cin>>dis;
			char c;
			cin>>c;
			if(c=='0'){
				for(int i=1;i<=n;i++){
					if(a[i][pos^1]){
						int p=(dis+i)%n;
						if(!p)p=n;
						a[p][pos]=1;
						a[i][pos^1]=0;
					}
				}
			}
			else if(c=='1'){
				for(int i=1;i<=n;i++){
					if(a[i][pos^1]){
						int p=(i+n-dis)%n;
						if(!p)p=n;
						a[p][pos]=1;
						a[i][pos^1]=0;
					}
				}
			}
			else{
				for(int i=1;i<=n;i++){
					if(a[i][pos^1]){
						int p=(dis+i)%n;
						if(!p)p=n;
						a[p][pos]=1;
						p=(i+n-dis)%n;
						if(!p)p=n;
						a[p][pos]=1;
						a[i][pos^1]=0;
					}
				}
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++){
			if(a[i][pos])ans++;
		}
		cout<<ans<<endl;
		for(int i=1;i<=n;i++)
			if(a[i][pos])cout<<i<<' ';
		cout<<endl;
		
	}
}

E - Rudolf and k Bridges

这个也不难吧。。单调队列滑窗
个人写滑窗的习惯是到了从能有答案的地方开始算然后把前面的放进去

#include<bits/stdc++.h>
#define ls (p<<1)
#define int long long
using namespace std;
const int maxn=105;
const int inf=1e17;
int read(){
	int ret=0,f=1;char c=getchar();
	while(c<'0'||c>'9') if(c=='-')f=-1,c=getchar();
	while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar();
	return ret*f;
}
int read(int a[]){
	char c=getchar();
	int j=0;
	while((c<'0')||(c>'9'&&c<'A')||(c>'Z'&&c<'a')||c>'z') c=getchar();
	while((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9')) 
		a[++j]=c-'a'+1,c=getchar();
	return j;
}
int cs[maxn];
deque<int>mn;
deque<int>mnn;
signed main(){
	int t=read();
	while(t--){
		int n=read(),m=read(),k=read(),d=read();
		int ans=inf,sum=0;
		d+=1;
		for(int i=1;i<=n;i++){
			int b=0;cs[i]=inf;
			for(int j=1;j<=m;j++){
				int v=read();
				if(j==1){
					b=1;
					continue;
				}
				while(!mnn.empty()&&(mnn.front()<(j-d)))
					mnn.pop_front(),mn.pop_front();
				while(!mn.empty()&&mn.back()>b)
					mnn.pop_back(),mn.pop_back();
				mnn.push_back(j-1),mn.push_back(b);
				v=mn.front()+v+1;
//				cout<<j<<' '<<v<<endl;
				b=v;
				if(j>=m-d&&j<m){
					cs[i]=min(cs[i],v+1);
				}
				else if(j==m){
					cs[i]=min(cs[i],v);
				}
				
			}
			
//			cout<<cs[i]<<endl;cout<<endl;
			
			sum+=cs[i];
			if(i>=k){
				sum-=cs[i-k];
				ans=min(ans,sum);
			}
			
		}
		cout<<ans<<endl;
	}

}

F - Rudolf and Imbalance

这个题嘞。。我一开始也是想分类讨论就是因为我是想直接二分找接近pmx的答案的。后面我观察了dalao的做法发现可以直接二分找中值(最佳值)在和pmx比较。。
不过就是因为中值不能确定一个最佳值,所以不能直接缩小到mid,要缩小到l=r-1然后把l和r都比较来找最佳值,这边我debug搞了很久一开始是直接用mid()

#include<bits/stdc++.h>
#define ls (p<<1)
#define int long long
using namespace std;
const int maxn=2e5+5;
int read(){
	int ret=0,f=1;char c=getchar();
	while(c<'0'||c>'9') if(c=='-')f=-1,c=getchar();
	while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar();
	return ret*f;
}
int read(int a[]){
	char c=getchar();
	int j=0;
	while((c<'0')||(c>'9'&&c<'A')||(c>'Z'&&c<'a')||c>'z') c=getchar();
	while((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9')) 
		a[++j]=c-'a'+1,c=getchar();
	return j;
}
int a[maxn],f[maxn],d[maxn];
signed main(){
	int t=read();
	while(t--){
		int mk=0;
		int n=read(),m=read(),k=read();
		int mx=0,pmx=0;
		for(int i=1;i<=n;i++){
			a[i]=read();
			if(i==1)continue;
			if(mx<=(a[i]-a[i-1])){
				pmx=mx;
				mx=a[i]-a[i-1];
				mk=i-1;
			}
		}
		
		for(int i=1;i<=m;i++)d[i]=read();
		sort(d+1,d+m+1);
		for(int i=1;i<=k;i++)f[i]=read();
		if(pmx==mx){
			cout<<mx<<endl;
			continue;
		}
		for(int i=1;i<=n-1;i++){
			if(a[i+1]-a[i]!=mx)pmx=max(a[i+1]-a[i],pmx);	
		}
		int lw=a[mk+1]-pmx,hi=a[mk]+pmx;
		int ans=mx;
	//	cout<<pmx<<' '<<mx<<"okok"<<endl;
		for(int i=1;i<=k;i++)
		{
			int l=1,r=m,mid=(l+r)>>1;
			int qub=(a[mk+1]+a[mk])/2;
			if((a[mk+1]+a[mk])%2)qub++;
			while(l+1<r){
				mid=(l+r)>>1;
				if(f[i]+d[mid]<qub)l=mid;
				else r=mid;
			}
			int q1=f[i]+d[r]-a[mk],q2=a[mk+1]-f[i]-d[r];
			ans=min(ans,max(q1,q2));
			q1=f[i]+d[l]-a[mk],q2=a[mk+1]-f[i]-d[l];
			ans=min(ans,max(q1,q2));
		}
		ans=max(pmx,ans);
		cout<<ans<<endl;
	}

}

G - Rudolf and Subway

这个题我不会啊。看题解的。
重新建图思路很巧妙。不过现在也知道了看到这种没办法直接搜索的图,肯定是要想办法重新建图的。

老规矩做题先看样例会发现就算是同一条地铁线路也是要乘车的。。。(除非是同一个点哈)

然后建图方法就是把颜色和地铁站直接连边,不管地铁站之间的关系。这样子每个地铁站到不同颜色地铁站的的距离固定是二,最后除以2即可
又因为采用的是广搜,逐层遍历,所以搜到的路径一定是最短路()

#include<bits/stdc++.h>
using namespace std;
#define fir first
#define scd second
const int maxn=2e6+5;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
	return x*f;
}
signed main()
{
	int t=read();
	while(t--){
		int n=read(),m=read();
		vector<pair<int,int> >eg[n+5];
		int idx=n+1;
		map<int,int>mp;
		for(int i=1;i<=m;i++){
			int u=read(),v=read(),col=read();
			if(mp[col]==0){
				mp[col]=idx;
				idx++;
			}
			eg[u].push_back({v,mp[col]});
			eg[v].push_back({u,mp[col]});
			
		}
		vector<int>edg[idx+5];
		for(int i=1;i<=n;i++){
			for(int j=0;j<eg[i].size();j++){
				int c=eg[i][j].scd,v=eg[i][j].fir;
				edg[c].push_back(i);
				edg[i].push_back(c);
				edg[c].push_back(v);
				edg[v].push_back(c);
			}
		}
		int s=read(),t=read();
		
//		cout<<s<<t<<"okok"<<endl;
		if(s==t){
			cout<<0<<endl;
			continue;
		}
		vector<int> d(idx+5,0);
		vector<int> vis(idx+5,0);
		queue<int>q;
		q.push(s);vis[s]=1;d[s]=0;
		while(!q.empty()){
			int u=q.front();
			q.pop();
			for(int i=0;i<edg[u].size();i++){
				if(!vis[edg[u][i]]){
					q.push(edg[u][i]);
					d[edg[u][i]]=d[u]+1;
					vis[edg[u][i]]=1;
				}
			}
		}
		if(!d[t])cout<<"-1"<<endl;
		else cout<<d[t]/2<<endl;
		
	} 
}
posted @ 2024-09-11 18:40  lyrrr  阅读(51)  评论(0)    收藏  举报