CCF CSP 202212-2 训练计划 C++代码

问题描述

试题编号:202212-2
试题名称:训练计划
时间限制:1.0s
内存限制:512.0MB
问题描述:

问题背景

西西艾弗岛荒野求生大赛还有 n 天开幕!

问题描述

为了在大赛中取得好成绩,顿顿准备在 n 天时间内完成“短跑”、“高中物理”以及“核裂变技术”等总共 m 项科目的加强训练。其中第 i 项(1≤i≤m)科目编号为 i,也可简称为科目 i。已知科目 i 耗时 ti 天,即如果从第 a 天开始训练科目 i,那么第 a+ti−1 天就是该项训练的最后一天。

大部分科目的训练可以同时进行,即顿顿在同一天内可以同时进行多项科目的训练,但部分科目之间也存在着依赖关系。如果科目 i 依赖科目 j,那么只能在后者训练结束后,科目 i 才能开始训练。具体来说,如果科目j 从第 a天训练到第 a+tj−1 天,那么科目 i 最早只能从第 a+tj 天开始训练。还好,顿顿需要训练的m 项科目依赖关系并不复杂,每项科目最多只依赖一项别的科目,且满足依赖科目的编号小于自己。那些没有任何依赖的科目,则可以从第 1 天就开始训练。

对于每一项科目,试计算:

1)最早开始时间:该科目最早可以于哪一天开始训练?

2)最晚开始时间:在不耽误参赛的前提下(n 天内完成所有训练),该科目最晚可以从哪一天开始训练?

n天内完成所有训练,即每一项科目训练的最后一天都要满足 ≤n。需要注意,顿顿如果不能在n 天内完成全部 m 项科目的训练,就无法参加大赛。这种情况下也就不需要再计算“最晚开始时间”了。

输入格式

从标准输入读入数据。

输入共三行。

输入的第一行包含空格分隔的两个正整数 n 和 m,分别表示距离大赛开幕的天数和训练科目的数量。

输入的第二行包含空格分隔的 m 个整数,其中第 i 个(1≤i≤m)整数 pi 表示科目 i 依赖的科目编号,满足 0≤pi<i;pi=0 表示科目 i 无依赖。

输入的第三行包含空格分隔的 m 个正整数,其中第 i 个(1≤i≤m)数 ti 表示训练科目 i 所需天数,满足 1≤ti≤n。

输出格式

输出到标准输出中。

输出共一行或两行。

输出的第一行包含空格分隔的 m 个正整数,依次表示每项科目的最早开始时间。

如果顿顿可以在 n 天内完成全部 m 项科目的训练,则继续输出第二行,否则输出到此为止。

输出的第二行包含空格分隔的 m个正整数,依次表示每项科目的最晚开始时间。

样例 1 输入

105
00000
123210

样例 1 输出

11111
109891

样例 1 说明

五项科目间没有依赖关系,都可以从第 1 天就开始训练。

10 天时间恰好可以完成所有科目的训练。其中科目 1 耗时仅 1 天,所以最晚可以拖延到第 10 天再开始训练;而科目 5 耗时 10 天,必须从第 1 天就开始训练。

样例 2 输入

107
0103230
21631043

样例 2 输出

1 3 1 7 4 7 1

样例 2 说明

七项科目间的依赖关系如图所示,其中仅科目 5 无法在 10 天内完成训练。


具体来说,科目 5 依赖科目 2、科目 2 又依赖于科目 1,因此科目 5 最早可以从第 4 天开始训练。

样例 3 输入

105
01234
1010101010

样例 3 输出

1 11 21 31 41

子任务

70% 的测试数据满足:顿顿无法在n天内完成全部 m项科目的训练,此时仅需输出一行“最早开始时间”;

全部的测试数据满足 0<n≤365 且 0<m≤100。

解答:

纯小白,使用的办法也是最简单理解的结构体加数组的暴力解法,大佬就不用看了。

将所有的依赖关系存储起来,然后根据依赖关系更改前后两个科目的开始时间、结束时间等。

具体可看代码,其中含有注释,简单易懂。

#include <bits/stdc++.h>
using namespace std;
struct xl{
	int kaishi;				//最早开始时间 
	int len;				//持续时长 
	int jieshu;				//结束时间(用于判断是否超过了总时长n) 
	int yilai;				//该项目是否依赖于某个前面的项目 
	int tuichi=999;			//该项目最早开始时间最多可以推迟多久,即得到最晚开始时间 
	bool genggai=false;		
//该项目的推迟时间是否已经被更改过,如果是,说明某一个后面的项目以来该项目,且那个项目已经算出来的最多推迟时间
//那么该项目的最多推迟时间应该等于后面那个项目的最多推迟时间(不然后面那个项目就超时了) 
};
int main()
{
	int n,m;
	cin>>n>>m;
	xl a[m+1];		
	a[0].jieshu=0;			//多存一个a[0],这样就不用每次都判断是否有依赖的前一项目 
	a[0].yilai=0; 
	for(int i=1;i<=m;i++)
	{
		cin>>a[i].yilai;	//存储每个项目的依赖关系 
	}
	for(int i=1;i<=m;i++)
	{
		cin>>a[i].len;		//每个项目时常 
	}
	bool chaoshi=false;
	for(int i=1;i<=m;i++)
	{
		a[i].kaishi=a[a[i].yilai].jieshu+1;		//最早开始时间就等于该项目依赖的前一项目的结束时间+1 
		a[i].jieshu=a[i].kaishi+a[i].len-1;		//最早开始的话,对应的该项目结束时间 
		if(a[i].jieshu>n) chaoshi=true;			//超时判断 
		cout<<a[i].kaishi<<" ";
	}
	if(!chaoshi)
	{
		cout<<endl;
		for(int i=m;i>=0;i--)
		{
			if(!a[i].genggai) a[i].tuichi=n-a[i].jieshu;
			//如果该项目未经过更改,则表明后面没有依赖该项目的其他项目,那么这个项目的最终结束时间就可以定为最后一天 
			//那么推迟时间就是最后一天减去预定的最早的结束时间 
			if(a[i].yilai!=0)	//如果该项目有依赖项目,那么该依赖项目的最多推迟时间等于该项目的推迟时间(否则后面的项目就会超时) 
			{
				a[a[i].yilai].tuichi=min(a[a[i].yilai].tuichi,a[i].tuichi);//有可能有多个后面的科目都依赖该科目,
//那么该科目能推迟的最长时间应该是后面所有相关科目的推迟时间的最小值
//(比如上面例子的图,两个科目都与3有关,那么3能够推迟的时间就应该取4、6两个科目推迟时间的最小值)
				a[a[i].yilai].genggai=true;		//标记依赖项目已经过更改,这样循环到依赖项目时就不能再用n-jieshu来计算推迟时长了
			}
		}
		for(int i=1;i<=m;i++)
		{
			cout<<a[i].kaishi+a[i].tuichi<<" ";
		}
	}
	return 0;
}

​

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
根据引用\[1\]和引用\[3\]的信息,我们可以得知顿顿需要在n天时间内完成m项科目的加强训练。每项科目有一个编号,编号为i,其中1≤i≤m。每项科目的训练时间为ti天,即从第a天开始训练科目i,训练将持续到第a+ti−1天。科目之间存在依赖关系,如果科目i依赖科目j,那么只能在科目j训练结束后,科目i才能开始训练。 对于csp202212-2题目中的c++训练计划,我们需要知道c++训练的编号以及训练的时间。根据题目描述,我们可以得知c++训练的编号为2。然而,题目中没有提供c++训练的具体时间。因此,我们无法确定c++训练的时间。 综上所述,我们无法确定c++训练的具体计划。 #### 引用[.reference_title] - *1* *3* [CCF CSP 202212-2 训练计划C++)](https://blog.csdn.net/qq_46092061/article/details/129207826)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [CCF-CSP真题《202212-2 训练计划》思路+python题解](https://blog.csdn.net/weixin_53919192/article/details/129084465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值