2022年CCF-CSP考前冲刺

202212-1现值计算

思路
本题很简单,按照题目所给条件输入输出就行。
注意有效数字。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n;
double i;
int q[N];
double all;

int main(){
	cin>>n>>i;
	for(int j=0;j<=n;j++){
		cin>>q[j];
		all+=q[j]*pow(1+i,-j);
	}
	printf("%.3lf",all);
	return 0;
}

202212-2训练计划

思路
本题重在分析题目所给案例。
根据分析我们可以知道,最早开始时间和自己的依赖有关;最晚开始时间和依赖自己的以及自己的消耗时间有关。
如果有依赖的话,最早开始时间就是依赖的最早时间加上依赖的消耗的时间。没有的话就是第一天。
如果有被依赖的话,最晚开始时间就是依赖你的科目的最小的最晚开始时间-你自己科目所消耗的时间。
然后计算最晚开始时间时,我们从最后的科目往前推。因为第i个科目依赖的肯定是他之前的项目。
代码

#include<bits/stdc++.h>
using namespace std;

const int N=101;
int n,m;
int p[N],t[N];
int earliest[N],latest[N];

int main(){
	int mark=1;
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>p[i];
	for(int i=1;i<=m;i++) cin>>t[i];
	//将每个科目的最早时间确定
	for(int i=0;i<=m;i++){
		if(p[i]==0) earliest[i]=1;
		else earliest[i]=earliest[p[i]]+t[p[i]];
		//判断所有科目最早开始的情况是否可以完成所有科目
		if(earliest[i]+t[i]-1>n)
			mark=0; 
	} 
	//输出每项科目的最早开始时间
	for(int i=1;i<=m;i++)
		cout<<earliest[i]<<" ";
	cout<<endl;
	//确定每个科目的最晚开始时间,从最后的科目往前推,需要把依赖该科目的科目所消耗时间算上 
	if(mark==1){
		for(int i=m;i>=1;i--){
			int temp=366;
			for(int j=i+1;j<=m;j++){
				//寻找是否有依赖该科目科目
				if(p[j]==i)
					temp=min(temp,latest[j]); 
			}
			//如果没有被依赖,那么最晚开始时间=最后期限-持续时间的时刻
			if(temp==366)
				latest[i]=n-t[i]+1;
			//如果有被依赖,那么最晚开始时间=依赖他的科目的最晚开始时间最小的科目- 本身持续的时间
			 else
			 	latest[i]=temp-t[i]; 
		}
		//输出每项科目的最晚开始时间
		for(int i=1;i<=m;i++)
			cout<<latest[i]<<" ";
	} 
	return 0;
}

202209-1如此编码

思路
按照题目最后给的提示,推出怎么求b[i]即可。
我们先求c[i]
观察图标得知c[0]=0
然后用b[i]=(m%c[i]-m%c[i-1])/c[i-1]求出b[i]即可
代码

#include<bits/stdc++.h>
using namespace std;

int a[21];
int b[21];
int c[21];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	c[0]=1;
	int tmp=1;
	for(int i=1;i<=n;i++){
		tmp*=a[i];
		c[i]=tmp;//累乘 
	}
	tmp=0;
	for(int i=1;i<=n;i++){
		//先存整个(Ci-1)*Bi
		b[i]=(m%c[i]-m%c[i-1])/c[i-1];
	}
	for(int i=1;i<=n;i++)	cout<<b[i]<<" ";
	return 0;
}

202209-2何以包邮?

思路
本题采用动态规划思想,即先把每个可能的花费给他记上。
(j-tmp>=0&&s[j-tmp]==1)减去它为正,而且减去它也有一种价格策略
然后从x开始向后,找到第一个大于x的价格,输出即可。
代码

#include<bits/stdc++.h>
using namespace std;
int s[300010];
int main(){
	int n,x;
	cin>>n>>x;
	s[0]=1;
	for(int i=0;i<n;i++){
		int tmp;
		cin>>tmp;
		//记录价格从0到300009的状态 
		for(int j=300009;j>=tmp;j--){
			if(j-tmp>=0&&s[j-tmp]==1){
				s[j]=1;
			}
		}
	}
	//从x开始算起,大于x的第一个价格就给他输出 
	for(int i=x;i<=300009;i++){
		if(s[i]==1){
			cout<<i;
			break;
		}
	}
}

202206-1归一化处理

思路
按照题目描述来即可。
代码

#include<bits/stdc++.h>
using namespace std;
double a[1010],f[1010];
int main(){
	int n;
	double sum=0,sum1=0,D,d;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
	}
	double avg=sum/n;
	for(int i=1;i<=n;i++){
		sum1+=pow((a[i]-avg),2);
	}
	D=sum1/n;
	d=sqrt(D);
	for(int i=1;i<=n;i++){
		f[i]=(a[i]-avg)/d;
		printf("%.16lf\n", f[i]); 
	}
}

202206-2寻宝!大冒险!

思路
用A[n][2]来存储n棵树的x、y坐标
然后输入藏宝图,并用num记录藏宝图中树的棵树。
然后找符合藏宝图的区域,并用tmp记录下数量。
在tmp=num,即棵树相等的情况下,遍历藏宝图B判断是否满足条件:
①是否超边界
②是否不满足响应的位置树的有无
③如果都满足,那就找对应的横纵坐标,找到ans++,然后直接进行下一次循环。
ans++用flag来判断
代码

int main(){
	int n,l,s; // 定义了三个整数变量n、l、s,分别表示树木数量、绿化图大小和藏宝图大小
	cin>>n>>l>>s; // 从输入中读取n、l、s的值

	int A[n][2]; // 定义了一个大小为n×2的二维数组A,用于存储树木的坐标
	int B[s+1][s+1]; // 定义了一个大小为(s+1)×(s+1)的二维数组B,用于存储藏宝图的信息

	for(int i=0;i<n;i++){
		cin>>A[i][0]>>A[i][1]; // 从输入中读取每棵树的横纵坐标,并存储到数组A中
	}

	int num=0; // 用于记录小地图中树木的数量
	for(int i=s;i>=0;i--){
		for(int j=0;j<=s;j++){
			cin>>B[i][j]; // 从输入中读取每个位置的信息,并存储到数组B中
			if(B[i][j]==1)
				num++; // 如果该位置有树木,则树木数量加1
		}
	}

	int ans=0; // 用于记录符合条件的结果数量
	for(int i=0;i<n;i++){
		int p=A[i][0],q=A[i][1]; // 用p、q来代表每棵树的横纵坐标
		bool flag=true; // 标记变量,表示当前树木是否符合条件
		int tmp=0; // 用于记录与当前树木在小地图中位置相同的树木数量

		for(int j=0;j<n;j++){
			if(A[j][0]-p>=0&&A[j][0]-p<=s&&A[j][1]-q>=0&&A[j][1]-q<=s){
				tmp++; // 统计与当前树木在小地图中位置相同的树木数量
			}
		}

		// 先比较树木数量是否相等
		if(tmp==num){
			for(int j=0;j<s+1;j++){
				for(int m=0;m<s+1;m++){
					if(p+j>l||q+m>l){
						flag=false; // 如果当前树木超出绿化图的范围,则标记为不符合条件
						break;
					}
					if(B[j][m]==0){
						for(int k=0;k<n;k++){
							if(A[k][0]==p+j&&A[k][1]==q+m){
								flag=false; // 如果当前位置有树木而树木集合中没有相应的树木,则标记为不符合条件
								break;
							}
						}
					}
					else{
						for(int k=0;k<n;k++){
							if(A[k][0]==p+j&&A[k][1]==q+m)
								break;
							if(k==n-1)
								flag=false; // 如果当前位置没有树木而树木集合中有相应的树木,则标记为不符合条件
						}
					}
				}
			}
			if(flag){
				ans++; // 如果当前树木符合条件,则结果数量加1
			}
		}
	}

	cout<<ans; // 输出符合条件的结果数量
}

202203-1未初始化警告

思路
只要右边的数在左边没有出现过,就不行。(0除外)
所以我们想到要用一个布尔数组来判断这个值是否有出现过。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
bool q[N];
int n,k;
int x,y;
int res;

int main(){
	q[0]=true;
	cin>>n>>k;
	while(k--){
		cin>>x>>y;
		if(!q[y]) res++;
		q[x]=true;
	}
	cout<<res<<endl;
	return 0;
} 

202203-2出行计划

思路1
按照题目来,正常的遍历看符不符合只能拿70分。
代码

#include<bits/stdc++.h>
using namespace std;
//tmp+k tmp+k+y
const int N=200005;
int t[N],c[N];
int main(){
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=0;i<n;i++){
		cin>>t[i]>>c[i];
	}
	for(int i=0;i<m;i++){
		int tmp,x,y,sum=0;
		cin>>tmp;
		x=tmp+k;
		for(int j=0;j<n;j++){
			y=tmp+k-1+c[j];
			if(t[j]<=y&&t[j]>=x) sum++;
		}
		cout<<sum<<endl;
	}
}

思路2
采用差分,缩小时间复杂度。
在这里插入图片描述
代码

#include<bits/stdc++.h>
using namespace std;
//tmp+k tmp+k+y
const int N=200005;
int q[N];
int main(){
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=0;i<n;i++){
		int t,c;
		cin>>t>>c;
		
		//在l,r时间段内做核酸,即t时刻可以进入
		int l=max(t-k-c+1,0);
		int r=max(0,t-k);
		q[l]++;
		q[r+1]--;
	}
	for(int i=1;i<200001;i++){
		q[i]+=q[i-1];
	}
	for(int i=0;i<m;i++){
		int x;
		cin>>x;
		cout<<q[x]<<endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值