SMU Summer 2024 Contest Round 5(7.19)

Robot Takahashi

题目链接

C - Robot Takahashi (atcoder.jp)

题目大意

题目给你应该长为n 的字符串,该字符串只包含0 和1 ,其中0 代表小孩,1代表大人,接着再给你n 个数代表每个0和1 对应的体重。有一个机器人,你可以给他赋一个X ,这个机器人就会根据这个X去判断,小于X的儿童小孩,大于等于X的是大人,设f(X)是这个机器人正确判断他们是小孩还是大人的人数。题目要求你去求f(X)的最大值

解题思路

题目要求是让你去找一个值,使得满足大于等于该体重的大人和小于该体重的小孩尽可能多,问满足条件的大人小孩加起来最多是多少人。

那么我们是不是就可以将所有人的身份和体重存入一个结构体中,然后对结构体进行排序,排序标准是:体重小的排前面,体重大的排后面,如果体重相等,则大人排前面(为什么体重相等要让大人排前面呢?我们可以先看一下我们的解题思路)

当我们排好序了之后,我们可以设一个l 和 r ,l 表示当前点往左的小于当前点体重的小孩的人数, r 表示当前点及往右的大于等于当前点体重的大人的人数。此时的 l+r 即为如果X为当前点的体重,那么f(X)的值,我们需要遍历每个点的l 和 r 取其中出现的最大的 l+r 即可

代码如下

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct nuu
{
	int si;
	int wi;
};
int main()
{
	int n;
	scanf("%d", &n);
	char a[n+1];
	scanf("%s", a);
	nuu b[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d", &b[i].wi);
		if(a[i]=='0')
			b[i].si=0;
		else
			b[i].si=1;
	}
	sort(b, b+n, [](nuu ai, nuu bi){return ai.wi<bi.wi||(ai.wi==bi.wi&&ai.si>bi.si);});
	
	int l0=0, r1=0;
	for(int i=0;i<n;i++)
	{
		if(b[i].si==1)
			r1++;
	}
	//printf("l%d  r%d\n", l0, r1);
	int maxx=-1;
	if(r1==0)
	{
		maxx=n;
		goto f;
	}
	for(int i=0;i<n;i++)
	{
		//printf("i%d    l%d r%d\n", i, l0, r1);
		maxx=max(maxx, l0+r1);
		if(b[i].si==0)
			l0++;
		else
			r1--;
	}
	f:
		printf("%d\n", maxx);
		return 0;
}

Connect 6

题目链接

C - Connect 6 (atcoder.jp)

题目大意

这道题的题目真是给我看懵了,其实他是什么意思呢,就是给你两个#,让你去下棋,看能不能有6个及以上的#连在一起,怎么样才算连在一起呢?就像五子棋那样……(就是怎么连,我读题的时候没读懂T_T)

解题思路

因为题目给的N最大也就1000,所有两重循环遍历的去找满足条件的情况是足够的

代码如下

#include<stdio.h>
int main()
{
	int n;
	scanf("%d", &n);
	char a[n+1][n+1];
	for(int i=0;i<n;i++)
	{
		scanf("%s", a[i]);
	}
	int bj=0;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			//右
			if(j+5<n)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i][j+o]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//左
			if(j-5>=0)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i][j-o]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//下
			if(i+5<n)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i+o][j]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//上
			if(i-5>=0)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i-o][j]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//右下
			if(i+5<n&&j+5<n)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i+o][j+o]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//右上
			if(i-5>=0&&j+5<n)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i-o][j+o]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//左下
			if(i+5<n&&j-5>=0)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i+o][j-o]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
			}
			//左上
			if(i-5>=0&&j-5>=0)
			{
				int xn=0;
				for(int o=0;o<=5;o++)
				{
					if(a[i-o][j-o]=='#')
						xn++;
				}
				if(xn+2>=6)
				{
					bj=1;
					goto f;
				}
				}
		}
	}
	f:
		
	if(bj==1)
		printf("Yes\n");
	else
		printf("No\n");
	
	return 0;
}

Strange Balls

题目链接

D - Strange Balls (atcoder.jp)

题目大意

这道题就是给你n个数,我们假设其中一个数为k,那么题目的意思就是说,当有k 个是k的数连在一起的时候,那么这k 个数都会消掉,就像开心消消乐一样。题目要求的是什么呢?题目要求的是读入当前的k 后,之前输入的(包括刚刚输入的数)总共还存在多少个。

解题思路

所有我们的思路就是开一个数组a,每输入一个k数,如果当前数组中的个数大于等于k个,那么去遍历当前数往前的k-1个数,看是不是都是k,如果存在不是k的数那么数组a 下标ai++,然后去读入下一个数,如果都是k ,那么把数组a 的下标往前以 k位,再ai++

代码如下

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct nuu
{
	int si;
	int wi;
};
int main()
{
	int n;
	scanf("%d", &n);
	char a[n+1];
	scanf("%s", a);
	nuu b[n];
	for(int i=0;i<n;i++)
	{
		scanf("%d", &b[i].wi);
		if(a[i]=='0')
			b[i].si=0;
		else
			b[i].si=1;
	}
	sort(b, b+n, [](nuu ai, nuu bi){return ai.wi<bi.wi||(ai.wi==bi.wi&&ai.si>bi.si);});
	
	int l0=0, r1=0;
	for(int i=0;i<n;i++)
	{
		if(b[i].si==1)
			r1++;
	}
	//printf("l%d  r%d\n", l0, r1);
	int maxx=-1;
	if(r1==0)
	{
		maxx=n;
		goto f;
	}
	for(int i=0;i<n;i++)
	{
		//printf("i%d    l%d r%d\n", i, l0, r1);
		maxx=max(maxx, l0+r1);
		if(b[i].si==0)
			l0++;
		else
			r1--;
	}
	f:
		printf("%d\n", maxx);
		return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值