Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第1张图片Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第2张图片

A题Three Pairwise Maximums

题意:给出xyz三个数,其中

求abc的值或者说不存在

思路:对应反推出a=min(x,y),b=min(x,z),c=min(y,z)是解之一。然后按原条件验证,符合条件就是YES否则就是NO。

代码:

#include 
using namespace std;
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		int a,b,c;
		a=min(x,y);
		b=min(x,z);
		c=min(y,z);
		if (x==max(a,b)&&y==max(a,c)&&z==max(b,c))
		{
			printf("YES\n");
			printf("%d %d %d\n",a,b,c);
		}
		else
		{
			printf("NO\n");
		}
	}
} 

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第3张图片

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第4张图片

B. Restore the Permutation by Merger

题意:给出一个数组,长度为2n,是n长度的排列数组和其自身交叉而得,求n长度的排列数组

解法:找每个数第一次出现,打印出即可。出现过就可以在另一个数组做一个标记,然后直接跳过即可。

代码:

#include 
int a[105];
int b[105];
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int n;
		scanf("%d",&n);
		memset(b,0,sizeof(b));
		for (int i=0;i<2*n;i++)
		{
			scanf("%d",&a[i]);
		}
		for (int i=0;i<2*n;i++)
		{
			if (b[a[i]]==0)
			{
				b[a[i]]=1;
				printf("%d ",a[i]);
			}
		}
		printf("\n");
	}
} 

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第5张图片

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第6张图片

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第7张图片

C. Make It Good

题意:先吐槽一下这题题目真的是又臭又长,其实就是给你一个数组,让你去除一定的前缀,然后剩余的数组可以一个一个数的从最前取一个数或从最后取一个数,成为一个不减的数列。

比如452,先取最后的2,再取最前的4和5.

解法:看懂了题就很简单了,保证去除前缀后是一个先增后减的就行了。然后从最后开始,反过来先增后减,什么时候不能减了截止作为前缀去除。

#include 
int a[200005];
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int n;
		scanf("%d",&n);
		for (int i=0;i0;p--)
		{
			if (a[p]>a[p-1])
			{
				break;
			}
		}
		for (;p>0;p--)
		{
			if (a[p]

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第8张图片

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第9张图片

Codeforces Round #656 (Div. 3)前四题(比赛中做出来的)_第10张图片

D. a-Good String

题意:题目保证输入字符串的长度一定是2^k,k是一个整数

定义好string:

1. 只有一个字母

2.多于一个字母,但是其中一半全是c,一半是c+1的好string。

要求对输入的string把一些字母调整,找出最少要调整多少次,让输入的string变成一个好string

解法:理解什么叫好string,就是一半是c,一半是c+1的好string

因此定义两个数组,一个是res[k][i],一个是same[k][i]。其中k代表字母是k,i代表第i个字母。初始化res[k][i]表示将string第i个字母修改成k要修改的次数。(即相同为0相异为1)same[k][i]一样。

从线段树的思想去做dp,一层一层往上dp,直到到根节点,转移方程为:

res[k][i]=min(res[k+1][2*i]+same[k][2*i+1],same[k][2*i]+res[k+1][2*i+1]);
same[k][i]=same[k][2*i]+same[k][2*i+1];

然后直接打印res[0][0]即可。

代码如下:

#include 
using namespace std;
int a[200005];
int res[30][200005];//好式子 
int same[30][200005];//同式子 
string s;
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int n;
		scanf("%d",&n);
		cin>>s;
		for (int i=0;i

本场比赛就做出了四道题,作为一个退役的老人打打玩(服役的时候也没怎么好好打)。主要想着开拓思维,免得脑子变笨了,不过还是摆脱不了,60行以上的代码就不会写了的难点。。。明天争取把没写出来的三题补了。

你可能感兴趣的:(算法训练)