Codeforce Round 605 (div3)

A.Three Friends(枚举)

思路:输入之后排序,然后枚举所有的情况

  • a a b
    a+1看一下是不是b-a+b-a+a-a是不是等于0,等于0就输出不等于0就输出b-a+b-a+a-a-2;
  • a b b
    b-1看一下是不是b-a+b-a+b-b是不是等于0,等于0就输出不等于0就输出b-a+b-a+b-b-2;
  • a b c
    b不动 a+1,c-1 输出c-b+c-a+b-a
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main (){
	int q;
	long long ans1;
	vector<long long>v(3);
	cin>>q;
	while(q--){
		ans1=0;
		cin>>v[0]>>v[1]>>v[2];
		sort(v.begin(),v.end());
		if(v[2]==v[1]&&v[1]==v[0]){
			ans1 = 0;
			cout<<ans1<<endl;
			continue;
		}
		if(v[2]==v[1]&&v[1]>v[0]){
			v[2]--;
			v[1]--;
			ans1 = v[2]-v[1]+v[1]-v[0]+v[2]-v[0];
			if(ans1==0){
				cout<<ans1<<endl;
				continue;
			}
			ans1-=2;
			cout<<ans1<<endl;
			continue;
		}
		if(v[0]==v[1]&&v[1]<v[2]){
			v[0]++;
			v[1]++;
			ans1 = v[2]-v[1]+v[1]-v[0]+v[2]-v[0];
			if(ans1==0){
				cout<<ans1<<endl;
				continue;
			}
			ans1-=2;
			cout<<ans1<<endl;
			continue;
		}
		if(v[2]>v[1]){
			v[2]--;
		}
		if(v[1]>v[0]){
			v[0]++;
		}
		ans1 = v[2]-v[1]+v[1]-v[0]+v[2]-v[0];
		cout<<ans1<<endl;
	}
	
} 

B.Snow Walking Robot(枚举)

思路:统计串中四个字符的出现次数的u,d,r.l,一个点不走两次,必然有r=l=min(l,r),u=d=min(d,u),

  1. l=0&&u==0 输出0
  2. l=0&&u!=0 输出2
  3. l!=0&&u=0 输出2
  4. 输出 2l+2r 按照矩形输出要求的指令
#include<iostream>
#include<map>
using namespace std;
string  s;
int t;
map<char,int>mp;
int main (){
	cin>>t;
	while(t--){
		cin>>s;
		mp.clear();
		int len = s.size();
		for(int i = 0 ; i < len;i++)
			mp[s[i]]++;
		int ans = 0;
		int l = min(mp['R'],mp['L']);
		int u = min(mp['U'],mp['D']);
		mp['R'] = l;		
		mp['L'] = l;
		mp['U'] = u;		
		mp['D'] = u;
		if(l==0&&u==0){
			cout<<0<<endl;
			continue;
		}
		if(l==0){
			cout<<2<<endl;
			cout<<"UD"<<endl;
			continue;
		}
		if(u==0){
			cout<<2<<endl;
			cout<<"LR"<<endl;
			continue;
		}
		cout<<(l+u)*2<<endl;
		while(mp['R']>0){
			cout<<'R';
			mp['R']--;
		}
		while(mp['U']>0){
			cout<<'U';
			mp['U']--;
		}
		while(mp['L']>0){
			cout<<'L';
			mp['L']--;
		}
		while(mp['D']>0){
			cout<<'D';
			mp['D']--;
		}
		cout<<endl;
	}
}

C.Yet Another Broken Keyboard

思路:坏的键会分割出来的各个好的串,然后做法就变成了题目一开始说的在好的串里挑选字串的公式 l*(l+1)/2
会爆int 所以res必须用long long

#include<iostream>
#include<string>
#include<map>
using namespace std;
int n,k;
string s;
map<char,int>mp;
int main (){
	cin>>n>>k;
	cin>>s;
	int len = s.size();
	char c;
	for(int i = 0 ; i < k ;i++){
		cin>>c;
		mp[c]=1;
	}
	long long l=0;
	long long res = 0;
	int flag=0;
	for(int i = 0 ; i< len;i++){
		if(mp[s[i]]==1){
			flag = 0;
			l=0;
			while(i<len&&mp[s[i]]==1){
				i++;
				l++;
				if(mp[s[i]]!=1){
					flag=1;
					break;
				}
			}
			if(flag||i==len){
				res += (1+l)*l/2;
				flag=0;
			}
		}
	}
	cout<<res<<endl;
	
}

D.Remove One Element

思路:dp[i][j]表示到第i位置的时候有删除过j个元素, j取0,1

  1. a[i]>a[i-1]
    dp[i][0]=max(dp[i][0],dp[i-1][0]+1)
    dp[i][1]=max(dp[i][1],dp[i-1][1]+1)

  2. a[i]>a[i-2]
    dp[i][1]=max(dp[i][1],dp[i-2][0]+1)

#include <cstdio>
#include <algorithm>
#include<iostream> 
using namespace std;
const int maxn = 2e5 + 5;
int n,a[maxn];
int dp[maxn][2], ans;
int main() {
	std::ios::sync_with_stdio(false);
	cin>>n;
	for (int i = 1; i <= n; i++) 
		cin>>a[i];
	dp[1][0] = 1;
	for (int i = 2; i <= n; i++) {
		dp[i][0] = dp[i][1] = 1;
		if (a[i] > a[i - 1]) {
			dp[i][0] = max(dp[i][0], dp[i - 1][0] + 1);
			dp[i][1] = max(dp[i][1], dp[i - 1][1] + 1);
		}
		if (a[i] > a[i - 2]) {
			dp[i][1] = max(dp[i][1], dp[i - 2][0] + 1);
		}
		ans = max(ans, max(dp[i][0], dp[i][1]));
	}
	cout<<ans;
	return 0;
}

E.Nearest Opposite Parity

看了之后显然要建图,求所有点的最短路径,但是在求得过程中,很明显每个点都求一遍超时,例如给你2*10个2,比赛结束想了一下只要建立2个超级源点:代替所有的偶数点,代替所有的奇数点。这样只要求两遍最短路就可以了。假如现在跑完了奇数的超级源点,显然所有的偶数点的答案就是与超级源点最近距离。详情看代码。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

const long long inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2e6+100;

bool vis[maxn];

int head[maxn];

long long res[maxn];
long long dis[maxn];

struct node{
	int v,nex,d;
}node[maxn];

int n,tot;

int a[maxn];

void init(){
	for(int i=1;i<=2+n;i++){
		dis[i]=inf;
		vis[i]=false;
	}
}

void addedge(int u,int v,int d){
	node[++tot].v = v;
	node[tot].nex = head[u];
	node[tot].d = d;
	head[u]=tot;
} 

void spfa(int u){
	queue<int>q;
	q.push(u);
	vis[u]=true;
	dis[u]=0;
	while(!q.empty()){
		u = q.front();
		q.pop();
		vis[u]=false;
		for(int i=head[u];~i;i=node[i].nex){
			int v = node[i].v;
			if(dis[v]>dis[u]+node[i].d){
				dis[v]=dis[u]+node[i].d;
				if(!vis[v]){
					q.push(v);
					vis[v]=true; 
				} 
			}
		}
	}
} 


int main(){
	std::ios::sync_with_stdio(false);
	cin>>n;
	memset(head,-1,sizeof(head));
	for(int i=1;i<=n;i++){
		cin>>a[i];
		if(a[i]+i<=n) addedge(a[i]+i,i,1);
		if(i-a[i]>=1) addedge(i-a[i],i,1);
	}
	for(int i=1;i<=n;i++){
		if(a[i]%2) addedge(n+1,i,0);
		if(a[i]%2==0) addedge(n+2,i,0);
	}
	init();
	spfa(n+1);
	for(int i=1;i<=n;i++)
		if(a[i]%2==0) res[i] = dis[i];
	
	init();
	spfa(n+2);
	for(int i=1;i<=n;i++)
		if(a[i]%2) res[i] = dis[i];
	for(int i=1;i<=n;i++){
		if(res[i]==inf){
			cout<<-1<<" ";
		}
		else {
			cout<<res[i]<<" ";
		}
	}
}

*终究是菜鸡,做的时候第二题都能错三遍- - **

发布了10 篇原创文章 · 获赞 1 · 访问量 177

猜你喜欢

转载自blog.csdn.net/weixin_43626356/article/details/103529551
今日推荐