CSP-J2019题解

声明:

本文章可能与洛谷题解相似。

CSP-J2019:

2019第一题 数字游戏

2019年第一题真水啊,但是根据著名的难度守恒定律,后面肯定难
循环一下字符串,计数一下有多少个1就行了

#include <bits/stdc++.h>
using namespace std;
int main(){
	int sum=0;
	for(int i=1;i<=8;i++){
		char a = getchar();
		if(a=='1') sum++;
	}
	cout<<sum;
	return 0;
}
2019第二题 公交换乘

一道模拟题,看完题目之后思路是比较清晰的:
如果是要坐地铁,那么花钱直接坐(因为也没有关于地铁的优惠),得到的优惠票放到一个vector数组里保存
如果是要坐公交车,那么先遍历一下vector,看一下有没有能用的优惠票(公交车钱小于地铁钱,时间小于45分钟,没被用过),能用就用,没有能用的只能花钱。

#include <bits/stdc++.h>
using namespace std;
int n; 
struct node{
	int price,t,use;
};
vector<node> que;//地铁优惠券 
int id;
long long sum;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		if(x==0){
			int x,y;
			cin>>x>>y;
			sum+=x;
			que.push_back((node){x,y,0});
		}else{
			int x,y;
			cin>>x>>y;
			bool flag=0;
			for(int i=id;i<que.size();i++){
				if(y-que[i].t<=45){
					if(x<=que[i].price&&que[i].use==0){
						que[i].use=1;
						flag=1;
						break; 
					}
				}else id++;//把票扔了 
			}
			if(!flag) sum+=x;
		}
	}
	cout<<sum;
	return 0;
}
2019第三题 纪念品

一道神仙背包dp题,刚开始看到题目蒙了,难度在这里上去了
题目中说了,交易可以无限次,很明显是一道完全背包题目。
但是与完全背包不同的是,他可以当日买来又可以当日卖出。当然,买来的目的是为了找一个未来一天高价卖出,赚取利润
所以设dp[j]dp[j]中我现在拥有的钱数 相当于 我的背包容量
我今天买来的纪念品消耗的钱 相当于 我的背包重量
我未来某一天把纪念品卖出去,赚取利润 相当于 我的背包价值
于是又回到了一道完全背包题目。
循环k天,每天使用完全背包看看今天能净赚多少钱,加到总钱数。最后输出总钱数就行了。
小细节:每次第i天结束后要把你的dp数组清空

#include <bits/stdc++.h>
using namespace std;
int t,n,m;//天数,数量,钱数 
int dp[10005],a[1005][1005];
int main(){
	cin>>t>>n>>m;
	for(int i=1;i<=t;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j]; 
		}
	}
	int sum=0;
	for(int k=1;k<t;k++){
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++){
			for(int j=a[k][i];j<=m;j++){//完全背包正着遍历
				dp[j]=max(dp[j],dp[j-a[k][i]]+a[k+1][i]-a[k][i]);
			}
		}
		m+=dp[m];
	}
	cout<<m;
	return 0;
}
2019第四题 加工零件

一道最短路。感觉比上一题简单
第一眼,使用递归直接解决

结果,再看一眼,就会爆炸:这么大的数据直接爆掉

于是思考这样一个问题:
7要做5阶段的零件1要不要做?其实就是问7到1有没有长度为5的路径?
8做6阶段的零件1要不要做?其实就是8到1有没有长度为6的路径?
那么怎么求路径呢?又要dfs?
想一想,如果7到1有路径,那么9到1也绝对有,但是8到1就不一定有。因为一个点到1有长度为6的路径,则在来回走两步,这个点到1一定有长度为8的路径(点可以来回走),在来回走两步,有一定有长度为10的路径。

那么,不需要求路径,求这个点到1的奇偶最短路即可,如果最短路小于要求的路径并且奇偶性相同,则可以到达。
小彩蛋:dijkstra不用优先队列也能过

#include <bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
int n,m,q,dist[100005],dist2[100005];//dist记录奇数最短路,dist2记录偶数 
vector<int> a[100005];
void dfs(){
	memset(dist,0x3f,sizeof(dist));
	memset(dist2,0x3f,sizeof(dist2));
	queue<pii> que;
	for(int i=0;i<a[1].size();i++){
		dist[a[1][i]]=1;
		que.push(make_pair(a[1][i],1));
	}
	while(que.size()){
		auto f=que.front();
		que.pop();
		for(int i=0;i<a[f.first].size();i++){
			if(f.second%2==0){//当前是偶数,则后面是奇数 
				if(f.second+1<dist[a[f.first][i]]){
					dist[a[f.first][i]]=f.second+1;
					que.push(make_pair(a[f.first][i],dist[a[f.first][i]]));
				}
			}else{//同理
				if(f.second+1<dist2[a[f.first][i]]){
					dist2[a[f.first][i]]=f.second+1; 
					que.push(make_pair(a[f.first][i],dist2[a[f.first][i]]));
				}
			}
		}
		
	}
}
int main(){
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++){
		int x,y;
		cin>>x>>y;
		a[x].push_back(y);
		a[y].push_back(x);
	}
	dfs();
	for(int i=1;i<=q;i++){
		int x,y;
		cin>>x>>y;
		if(y%2==1){
			if(dist[x]<=y) cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
		}else{
			if(dist2[x]<=y) cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
		}
	}
	return 0;
}

后期会更新2020年的。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值