Educational Codeforces Round 107 (Rated for Div. 2)题解

题目链接

被B题卡到了,唉,还是自己人傻逼。

A题

题意:有三种类型的客人,他们依次到来,一种反对者,一种支持者,还一种观望者,即根据当前情况,如果反对数 > 支持数,就投反对,反之投支持的人,现在你有两个投票系统,你可以选择给当前来到的客人展示其中一种,问你最多可以获得多少票支持。

思路:显然就是支持者数目 + 观望者数目, 因为显然我们可以让反对只投到一个投票系统上。

int main()
{
	IOS;
	int T;
	cin >> T;
	while(T --)
	{
		int n;
		cin >> n;
		int up = 0, down = 0;
		for(int i = 0 ; i < n ; i ++)
		{
			int r;
			cin >> r;
			if(r == 1) up ++;
			else if(r == 2) down ++;
			else	up ++;
		}
		cout << up << "\n";
	}
	return 0;
}

B题

题意:给三个数\(a, b, c\), 让你找到两个数\(x\)\(y\),使得\(x,y,gcd(x, y)\)这三个数的位数分别是\(a,b,c\)

思路:显然是一个构造题,想办法构造即可。
我开始没写程序检验,想当然以为是对了,卡了半天,还wa了4发,心疼。
我构造的是往数的末尾添3和7的方法,但是注意\(gcd(1003, 17) = 17\)这个唯一的坑爹情况(下面的三目运算用途正是如此),由于数据范围不大,这种可以自己打表检验规避!!!
代码如下

int base[11];
 
int main()
{
	IOS;
	int T;
	cin >> T;
	base[1] = 0;
	int t = 1;
	for(int i = 2 ; i <= 10 ; i ++)
		t = t * 10, base[i] = t;
	while(T --)
	{
		int a, b, c;
		cin >> a >> b >> c;
		int x;
		if(a == 1) x = 1;
		else x = (base[a - c + 1] + (a >= b ? 7 : 3)) * (base[c] ? base[c] : 1);
		
		int y;
		if(b == 1) y = 1;
		else y = (base[b - c + 1] + (b > a ? 7 : 3)) * (base[c] ? base[c] : 1);
		cout << x << " " << y << endl;
	}
	return 0;
}

C题

题意:从前往后给你n张卡片,每个卡片都有一个颜色,然后有m次询问,每次询问找到最前面的这个颜色的卡片,输出它的下标,然后把它放到最开头去。

思路:由于卡片的颜色最多只有50种,显然我们只需要维护每种颜色最前面的卡片即可,因为后面的没有意义,我们从前面拿一张放到开头去,它的下标没有变化。
代码如下

int n, q;
int idx[55];
 
 
int main()
{
	IOS;
	cin >> n >> q;
	for(int i = 1 ; i <= n ; i ++)
	{
		int x;
		cin >> x;
		if(!idx[x]) idx[x] = i;
	}
	while(q --)
	{
		int p;
		cin >> p;
		cout << idx[p] << " ";
		for(int i = 1 ; i <= 50 ; i ++)
			if(idx[i] < idx[p])
				idx[i] ++;
		idx[p] = 1;
	}
 
	return 0;
}

D题

题意:让你用从'a'开始的前k个字母,构造一个字符串S(此处下标从1开始),使得满足\(1 <= i < j <= len(S),S_i = S_j , S_{i + 1} = S_{j + 1}\)\({i, j}\)对数最少。

思路:我们以双字符组成的串来看,可以选择hash把它们映射成\(0到675\)的数,根据上一个字母枚举当前字母,选择当前字母能构成的之前出现次数最少的双字符,每次尽量选择较后的字母,因为我们是从前往后枚举的,这样能最大化预留之后的选择空间。
代码如下

int cnt[700];
char s[N];

int main()
{
	IOS;
	int n, k;
	cin >> n >> k;
 
	s[0] = 'a';
	int last = 0;
	for(int i = 1 ; i < n ; i ++)
	{
		int mind = 1e9, d = -1;
		for(int j = 0 ; j < k ; j ++)
		{
			if(mind >= cnt[last * 26 + j])
			{
				mind = cnt[last * 26 + j];
				d = j;
			}		
		}
		cnt[last * 26 + d] ++;
		last = d;
		s[i] = d + 'a';
	}
 
	for(int i = 0 ; i < n ; i ++)
		cout << s[i];
 
	return 0;
}

E题

想了半个小时也没想出来,后面再补。
题意:

思路:
代码如下

posted @ 2021-04-13 01:55  beatlesss  阅读(542)  评论(2)    收藏  举报