Codeforces Round #605 (Div. 3)题解

Codeforces Round #605 (Div. 3)题解

A - Three Friends

题意:给出三个人的坐标,然后求出三个人最多移动一单元的情况下,三人坐标位置距离相隔最小值。

:暴力循环每种移动可能。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
	int q;
	scanf("%d",&q);
	while(q--)
	{
		long long ans = 5*10e9;
		int a[4];
		cin>>a[1]>>a[2]>>a[3];
		for(long long i = a[1]-1;i <= a[1]+1;i++)
		{
			for(long long j = a[2]-1;j <= a[2]+1;j++)
			{
				for(long long k = a[3]-1;k <= a[3]+1;k++) 
				ans = min(ans,abs(i-j)+abs(j-k)+abs(i-k));
			}
		}
		printf("%lld\n",ans);
	}	
	return 0;
} 

B - Snow Walking Robot

题意:机器人不能再次走同一个单元格(除原点外),给出移动字符序列,然后求出删掉最少字符个数后能使机器人走回原点的序列。

:只要L、R的个数相同且U、D的个数相同就可以使机器人走回原点。所以删掉多余的字符就可以。

/*
 
6
LRU
DURLDRUDRULRDURDDL
LRUDDLRUDRUL
LLLLRRRR
URDUR
LLL
 
 
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
	int q;
	scanf("%d",&q);
	while(q--)
	{
		int a = 0,b = 0,c = 0,d = 0;
		string s;
		cin>>s;
		int len = s.length();
		//printf("len = %d\n",len);
		for(int i = 0;i < len;i++)
		{
			if(s[i]=='U') a++;
			else if(s[i]=='D') b++;
			else if(s[i]=='L') c++;
			else if(s[i]=='R') d++;
		}
		int cnt = abs(a-b)+abs(c-d);
		a = min(a,b);
		c = min(c,d);
		//printf("cnt = %d,a = %d,c = %d\n",cnt,a,c);
		if(a==0&&c==0) printf("0\n");
		else
		{
			//printf("%d\n",len-cnt);
			if(a == 0)
			{
				printf("2\n");
				printf("LR\n");
			}else if(c == 0)
			{
				printf("2\n");
				printf("UD\n");
			}else
			{
				printf("%d\n",len-cnt);
				for(int i = 1;i <= a;i++) printf("U");
				for(int i = 1;i <= c;i++) printf("L");
				for(int i = 1;i <= a;i++) printf("D");
				for(int i = 1;i <= c;i++) printf("R");
				printf("\n");
			}
		}
	}	
	return 0;
} 

C - Yet Another Broken Keyboard

题意:给你一串只含小写字母字符串,和几个可用字母,求用所给字母能表示所给字符串中的子串数量。
:从头开始循环一遍,如果存在连续的可以打出的字符,cnt++,如果出现了不能打出的字符时,cnt = 1。每次出现可以打出的字符时,ans+=cnt。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
	int n,m;
	bool vis[30];
	long long ans = 0;
	memset(vis,0,sizeof(vis));
	cin>>n>>m;
	string s;
	cin>>s;
	char tmp;
	for(int i = 1;i <= m;i++)
	{
		cin>>tmp;
		getchar();
		vis[tmp-'a'] = 1;
	}
	long long cnt = 1;
	if(vis[s[0]-'a']) 
	{
		ans++;
		cnt++;
	}
	for(int i = 1;i < n;i++)
	{
		if(vis[s[i]-'a'])
		{
			ans+=cnt++;
		}else
		{
			cnt = 1;
		}
	}
	printf("%lld",ans);
	return 0; 
}

D - Remove One Element

题意:求删除一个元素后的最大的上升子序列的长度。
:分别记录第i个数前面的递增个数和后面的递增个数,
最后遍历所有的i,因为只有两种情况值最大:

  1. 第i个的递增个数
  2. 当arr[i-1]<arr[i+1]时,不要第i个时(i-1)前面的递增个数 + (i+1)后面的递增个数。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n;
int a[200005];
int l[200005];
int r[200005];
int main()
{
	cin>>n;
	for(int i = 1;i <= n;i++)
	{
		cin>>a[i];
		l[i] = 1;
		r[i] = 1;
	}
	int ans = 1;
	
	for(int i = 1;i < n;i++)
	{
		if(a[i] < a[i+1]) 
		{
			l[i+1] = l[i]+1;
		}
		ans = max(ans,l[i+1]);
	}
	
	for(int i = n;i > 1;i--)
	{
		if(a[i] > a[i-1]) 
		{
			r[i-1] = r[i]+1;
		}
		ans = max(ans,r[i-1]);
	}
	
	for(int i = 2;i < n;i++)
	{
		if(a[i-1] < a[i+1]) ans = max(ans,l[i-1]+r[i+1]);
	}
	printf("%d",ans);
	return 0;
}

E - Nearest Opposite Parity

题意:有一个长度为n的数组 a ,数组坐标从 1 到 n ,假设你现在处于数组中的某一个位置,我们假设这个坐标为 i ,那么:
如果 1<=i−a[i] ,那么你可以从坐标 i 移动到坐标 i−a[i] 位置(花费一步);
如果 i+a[i]<=n ,那么你可以从坐标 i 移动到坐标 i+a[i] 位置(同样花费一步)。
对于从 1 到 n 的所有坐标 i 来说,你想要的知道你最少需要几步可以从坐标 i 移动到一个坐标j ,
且 a[i] 和 a[j] 具有不同的奇偶性(也就是说,如果 a[i] 是偶数,那么 a[j] 就是奇数;如果 a[i] 是奇数,那么 a[j] 就得是偶数)。

:BFS,参考这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值