Educational Codeforces Round #107 (Div. 2)ABCD题解

A题

题目链接

https://codeforces.com/contest/1511/problem/A

题意

给定一个n和一个序列r1,r2,…,rn,说是给电影投票,每个ri表示投票类型,一共有三种类型,ri=1或者2或者3。1表示支持,2表示不支持,3表示如果目前不支持的人多就投不支持,否则投支持。同时有两个投票点,我们可以操作每个人去哪个点投票,问最多可以有多少人支持。

思路

贪心,将投票类型1和3都放入一个站点,不支持的放入一个站点,那么总票数就等于投票类型1和3的和。

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,u = 0,d = 0;
		scanf("%d",&n);
		while(n--)
		{
			int x;
			scanf("%d",&x);
			if(x==2) d++;
			else u++;
		}
		printf("%d\n",u);
	}
	return 0;
}
 

B题

题目链接

https://codeforces.com/contest/1511/problem/B

题意

给定三个整数a,b和c,需要求两个整数x和y,其中x在十进制中有a位,y在十进制中有b位,x和y的最大公因数在十进制中有c位。

思路

数论,可以这样考虑,我们有两个互质的整数,一个有a-c位,一个有b-c位,那么再给这两个数每个乘10c就有最大公因数10c。而对于这两个互质的数我们有这样的性质:
性质: 111…1(n个1)和100…0(1个1,后面全是0)一定是互质的。
证明:因为100…0的质因子只有2和5,而111…1的质因子不可能有2和5,所以他们互质。不可能的原因是,如果质因子有2,那么一定是偶数,矛盾,如果有5,那么个位一定是5或者0,也矛盾。
所以我们可以有1个1和a-1个0拼起来表示x,用b-c+1个1和c-1个0拼起来表示y输出。

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		printf("1");
		for(int i=1;i<a;i++) printf("0");
		printf(" ");
		for(int i=0;i<=b-c;i++) printf("1");
		for(int i=b-c+1;i<b;i++) printf("0");
		puts("");
	}
	return 0;
}
 

C题

题目链接

https://codeforces.com/contest/1511/problem/C

题意

找纸牌,桌子上有一对纸牌,从上到下编号依次是1到n,同时每张牌有一个数表示颜色,问每次从上往下找一张颜色为t的纸牌,只要找到就将其放入牌顶,同时输出找到时这张牌在第几张。

思路

模拟,用两个队列模拟,第一个双端队列模拟牌堆,第二个队列用来存找牌时清出来的堆顶的牌。

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
	deque<int> d;
	int n,q;
	scanf("%d%d",&n,&q);
	for(int i=0;i<n;i++)
	{
		int t;
		scanf("%d",&t);
		d.push_back(t);
	}
	
	while(q--)
	{
		int t,e,ans = 1;
		stack<int> s;
		scanf("%d",&t);
		while(d.front()!=t)
		{
			s.push(d.front());
			d.pop_front();
			ans++;
		}
		e = d.front();
		d.pop_front();
		printf("%d ",ans);
		while(!s.empty())
		{
			d.push_front(s.top());
			s.pop();
		}
		d.push_front(e);
	}
    return 0;
}

D题

题目链接

https://codeforces.com/contest/1511/problem/D

题意

给两个整数n和k,要求组成一个由k种小写字母组成的长度为n的字符串,这个字符串中重复的字符对出现的次数最少。字符对是指两个相邻的字符组成一对。

思路

dfs,设x为字符对前一个字母,y为后一个字母,那么就是x和y之间有一条边,以此用邻接表建图。因为有k个节点,那么就有k2条边,从’a’开始访问。以后每次访问都先访问没遍历到的字符对的情况。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    vector<vector<char> > v(k);
    vector<int> u(k);
    for(int i=0;i<k;i++)
    {
    	for(int j=0;j<k;j++)
    	{
    		v[i].push_back('a'+j);//建图
		}
	}
    int x = 0;
    for(int i=0;i<n;i++)//搜索
    {
    	printf("%c",v[x][u[x]]);
    	u[x] = (u[x]+1)%k;
    	x = u[x];
	}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值