解题报告: Codeforces Round #536 (Div.2)

解题报告: Codeforces Round #536 (Div.2)

能力不足,比赛时间结束时只解出A,B,C,D题。以下为这些题个人的解题思路及代码,不喜勿喷。

Problem A Lunar New Year and Cross Counting

题意

给你一个由字符组成的矩阵。

当位置(i, j),(i - 1, j - 1), (i - 1, j + 1), (i + 1, j - 1), (i + 1, j + 1)的字符均为’X’时组成一个“大叉”。

编写一个程序该矩阵中一共有多少个“大叉”。

解法

对于每一个不在边缘上的点,根据题意检查其是否符合标准即可。

以下是代码

//Codeforces Round #536 (Div.2)
//Problem A
//EnRonG 
#include <stdio.h>
#include <string.h>

int		n_Ans;
int		n_Size;
char	s_Matrix[501][501];

int main()
{
	scanf ("%d", &n_Size);
	
	for (int i = 0; i < n_Size; i++)
	{
		scanf ("%s", s_Matrix[i]);
	}
	
	for (int i = 1; i < n_Size - 1; i++)
	{
		for (int j = 1; j < n_Size - 1; j++)
		{
			if (s_Matrix[i][j] 			== 'X' && s_Matrix[i - 1][j - 1] == 'X' &&
				s_Matrix[i + 1][j - 1]	== 'X' && s_Matrix[i - 1][j + 1] == 'X' &&
				s_Matrix[i + 1][j + 1]	== 'X')
			{
				n_Ans++;
			}
		}
	}
	
	printf ("%d\n", n_Ans);
	
	return 0;
}

Problem B Lunar New Year and Food Ordering

题意

一个餐厅,售卖N种菜品,共有M个顾客。

每一种菜都有制作成本以及初始数量。

现这M个顾客按顺序进行点餐,每个顾客都会要求点某个菜并给出需要多少份这个菜。上菜规则有如下三条:

  1. 如果顾客点的这个菜的剩余数量多于顾客所需要的数量,则直接给顾客这么多菜,收入为该菜品的制作成本 x 顾客需要的数量
  2. 如果顾客点的这个菜的剩余数量少于顾客所需要的数量,将该菜品剩下的所有菜都给该顾客。并制作若干制作成本最低的菜品给该顾客,来补齐顾客需要的数量。收入即做好所有菜的成本。
  3. 如果顾客点的菜数量太多,餐厅无法提供足够的菜,收入为0,并且顾客提走剩下的所有的菜

现给出菜品数量、顾客数量、菜品制作成本、菜品初始剩余量、以及顾客的需求。

要求对于每个顾客的请求输出餐厅的收入。

解法

对于输入的菜品,对其按价格进行排序。

然后根据题意模拟过程即可。

//Codeforces Round #536 (Div.2)
//Problem B
//EnRonG 
#include <stdio.h>
#include <map>
#define SIZE 100010
using namespace std;

map		<long long, long long> m_Chart;

long long	n_Amount;
long long	n_DishID;
long long	n_TrueID;
long long	n_Find;
long long	n_TotCust;
long long	n_TotKind;
long long	n_TotRemain;
long long	n_NewID[SIZE];
long long	n_Cost[SIZE];
long long	n_RemainCnt[SIZE];
long long	n_Fee;

void	v_Swap(long long &n_Num1, long long & n_Num2)
{
	long long	n_Temp	= n_Num1;
	n_Num1				= n_Num2;
	n_Num2				= n_Temp;
}

void	v_Sort(long long n_Left, long long n_Right)
{
	if (n_Left > n_Right)
	{
		return;
	}
	
	long long	n_Left1		= n_Left;
	long long	n_Right1	= n_Right;
	long long	n_Temp		= n_Cost[n_Left];
	
	while (n_Left1 != n_Right1)
	{
		while (n_Cost[n_Right1] >= n_Temp && n_Left1 < n_Right1)
		{
			n_Right1--;
		}
		
		while (n_Cost[n_Left1] <= n_Temp && n_Left1 < n_Right1)
		{
			n_Left1++;
		}
		
		if (n_Left1 < n_Right1)
		{
			v_Swap(n_Cost[n_Left1], n_Cost[n_Right1]);
			v_Swap(n_RemainCnt[n_Left1], n_RemainCnt[n_Right1]);
			v_Swap(n_NewID[n_Left1], n_NewID[n_Right1]);
		}
	}
	
	v_Swap(n_Cost[n_Left], n_Cost[n_Left1]);
	v_Swap(n_RemainCnt[n_Left], n_RemainCnt[n_Left1]);
	v_Swap(n_NewID[n_Left], n_NewID[n_Left1]);
	
	v_Sort(n_Left, n_Left1 - 1);
	v_Sort(n_Left1 + 1, n_Right);
}

int main()
{
	scanf ("%I64d %I64d", &n_TotKind, &n_TotCust);
	n_Find	= 1;
	
	for (int i = 1; i <= n_TotKind; i++)
	{
		scanf ("%I64d", &n_RemainCnt[i]);
		n_TotRemain	+= n_RemainCnt[i];
		n_NewID[i]	= i;
	}
	
	for (int i = 1; i <= n_TotKind; i++)
	{
		scanf ("%I64d", &n_Cost[i]);
	}
	
	v_Sort(1, n_TotKind);
	
	for (int i = 1; i <= n_TotKind; i++)
	{
		m_Chart.insert(pair<long long, long long>(n_NewID[i], i));
	}
	
	for (int i = 1; i <= n_TotCust; i++)
	{
		scanf ("%I64d %I64d", &n_DishID, &n_Amount);
		
		if (n_TotRemain < n_Amount)
		{
			n_TotRemain	= 0;
			printf ("0\n");
			continue;
		}
		
		n_TrueID	= m_Chart[n_DishID];
		
		if (n_RemainCnt[n_TrueID] >= n_Amount)
		{
			n_TotRemain				-= n_Amount;
			n_RemainCnt[n_TrueID]	-= n_Amount;
			n_Fee					= n_Amount * n_Cost[n_TrueID];
		}
		
		else
		{
			n_Fee					= n_RemainCnt[n_TrueID] * n_Cost[n_TrueID];
			n_Amount				-= n_RemainCnt[n_TrueID];
			n_TotRemain				-= n_RemainCnt[n_TrueID];
			n_RemainCnt[n_TrueID]	= 0;
			
			while (n_Amount && n_Find <= n_TotKind)
			{
				while (!n_RemainCnt[n_Find] && n_Find <= n_TotKind)
				{
					n_Find++;
				}
				
				if (n_Find > n_TotKind)
				{
					break;
				}
				
				if (n_RemainCnt[n_Find] >= n_Amount)
				{
					n_RemainCnt[n_Find]		-= n_Amount;
					n_TotRemain				-= n_Amount;
					n_Fee					+= n_Amount * n_Cost[n_Find];
					n_Amount				= 0;
				}
				
				else
				{
					n_Fee					+= n_RemainCnt[n_Find] * n_Cost[n_Find];
					n_Amount				-= n_RemainCnt[n_Find];
					n_TotRemain				-= n_RemainCnt[n_Find];
					n_RemainCnt[n_Find]		= 0;
				}
			}
		}
		
		printf ("%I64d\n", n_Fee);
	}
	
	return 0;
}

反思

这份代码仍有待优化的地方,如果将每一个菜品的属性都放在一个结构体中,并重定向运算符<,利用stl库中的sort()函数可以提升该程序的运行效率,并简化代码。

Problem C Lunar New Year and Number Division

题意

给出N个数(保证N是偶数),将其分为M组。

求这M组数的和的平方的最小值。

解法

对于输入的这串数进行排序,每次取两端的数组成一组即可得最小值。

//Codeforces Round #536 (Div.2)
//Problem C
//EnRonG
#include <stdio.h>
#include <algorithm>
#define SIZE 300001
using namespace std;

long long	n_TotNum;
long long	n_Data[SIZE];
long long	n_Sum;

int main()
{
	scanf ("%I64d", &n_TotNum);
	
	for (int i = 1; i <= n_TotNum; i++)
	{
		scanf ("%I64d", &n_Data[i]);
	}
	
	sort(n_Data + 1, n_Data + n_TotNum + 1);
	
	for (int i = 1, j = n_TotNum; i < j; i++, j--)
	{
		n_Sum	+= (n_Data[i] + n_Data[j]) * (n_Data[i] + n_Data[j]);
	}
	
	printf ("%I64d\n", n_Sum);
	
	return 0;
}

Problem D Lunar New Year and a Wander

题意

N个点、M条边。

保证连通成一张图。

求以最小字典序遍历这张图的方案。

解法

从ID为1的点开始遍历。

每遍历到1个点就将其能达到的点加入set中,然后再选set中最小的点继续进行遍历即可。

//Codeforces Round #536 (Div.2)
//Problem D
//EnRonG
#include <stdio.h>
#include <string.h>
#include <set>
#define SIZE 100001
using namespace std;

struct Edge
{
	int	n_ToPoint;
	int	n_NextEdgeID;
}e_Edge[SIZE << 2];

int	n_From;
int	n_HandlePt;
int	n_To;
int	n_TotEdgeB;				//Counts Edges Already Built
int	n_TotEdge;
int	n_TotPoint;
int	n_Book[SIZE];
int	n_FirstEdge[SIZE];
int	n_InSet[SIZE];
set	<int>	s_Points;

void v_BuildEdge(int n_From, int n_To)
{
	n_TotEdgeB++;
	e_Edge[n_TotEdgeB].n_ToPoint	= n_To;
	e_Edge[n_TotEdgeB].n_NextEdgeID	= n_FirstEdge[n_From];
	n_FirstEdge[n_From]				= n_TotEdgeB;
	
	n_TotEdgeB++;
	e_Edge[n_TotEdgeB].n_ToPoint	= n_From;
	e_Edge[n_TotEdgeB].n_NextEdgeID	= n_FirstEdge[n_To];
	n_FirstEdge[n_To]				= n_TotEdgeB;
}

void v_GetAns(int n_CurPointID)
{
	printf ("%d ", n_CurPointID);
	
	if (n_CurPointID != 1)
	{
		s_Points.erase(n_CurPointID);
	}
	
	for (int i = n_FirstEdge[n_CurPointID]; i != 0;
	i = e_Edge[i].n_NextEdgeID)
	{
		n_HandlePt	= e_Edge[i].n_ToPoint;
		
		if (n_Book[n_HandlePt])
		{
			continue;
		}
		
		if (!n_InSet[n_HandlePt])
		{
			s_Points.insert(n_HandlePt);
			n_InSet[n_HandlePt]	= 1;
			n_Book[n_HandlePt]	= 1;
			
		}
	}
	set<int>::iterator	s_ITE;
			
	if (s_Points.size())
	{	
		s_ITE	= s_Points.begin();
		v_GetAns(*s_ITE);
	}
}

int main()
{
	scanf ("%d %d", &n_TotPoint, &n_TotEdge);
	
	for (int i = 1; i <= n_TotEdge; i++)
	{
		scanf ("%d %d", &n_From, &n_To);
		v_BuildEdge(n_From, n_To);
	}
	
	n_InSet[1]	= 1;
	n_Book[1]	= 1;
	
	v_GetAns(1);
	
	set<int>::iterator	s_ITE2;
	
	if (s_Points.size())
	{
		for (s_ITE2	= s_Points.begin(); s_ITE2 != s_Points.end();
		s_ITE2++)
		printf ("%d ", *s_ITE2);
	}
	
	printf ("\n");
	
	return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值