湘潭大学2022软件工程程序设计实践平时练习二C/C++

第1关:基金大师

  • 任务要求

题目描述

小明热爱基金,现在给你某支基金的每天的价格,请你帮他算算买卖1次或0次所得最大利润是多少? (0次即没有发生交易)

输入输出:

第一个整数m(0<m<100)表示天数 第二组输入个m个整数,每个整数为每天的价格,每个的整数的范围为0到100000

输入: 6 7 1 5 3 6 4 输出: 5

本题来源,《算法导论》。本题考察动态规划-对过去信息充分利用的思想。变量minn代表历史最低值。cache表示当前基金值。

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<map>
#include<cstring>
#include<sstream>
//#define int long long
using namespace std;
typedef long long ll;
const int N = 1000;
double dp[N + 10][N + 10];
int tu[N + 10][N + 10];
int num[N + 10];
int nex[200000];
int tong[120];
int32_t main() {
	int n;
	cin >> n;
	int minn = 987654321;
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		int cache;
		cin >> cache;
		minn = min(minn, cache);
		ans = max(ans, cache - minn);
	}
	cout << ans << endl;
}

第2关:奶茶店2

300

  • 任务要求

题目描述

XTU奶茶店又开张了,现给定不同种类奶茶的储存量、总售价和需求量,现在请你计算该奶茶店所能获得的最大收益。

输入格式

每个输出包含一个测试样例,先给出一个N(0<N<=1000)表示奶茶的种类数,再给出一个D(0<D<=10000)表示市场最大需求量。随后两行分别是奶茶的库存量M(0<M<=10000)和每种奶茶的总售价P(0<P<=10000)。

输出格式

输出该奶茶店所能获得的最大收益,保留两位小数

输入样例

3 20 18 15 10 75 72 45

输出样例

94.50

本题考察贪心-利润。优先贩卖单价高的奶茶以便获得更多利润。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int arr[1010];
int brr[1010];
vector<pair<double, int>> v;
int main() {
	int n, d;
	cin >> n >> d;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}
	for (int i = 1; i <= n; i++) {
		cin >> brr[i];
	}
	
	for (int i = 1; i <= n; i++) {
		v.push_back({brr[i]/(double)arr[i], arr[i]});
	}
	sort(v.begin(), v.end());
	reverse(v.begin(),v.end());
	double ans = 0;
	for (auto it : v) {
		ans+=it.first*min(it.second,d);
		d-=min(it.second,d);
		if(d==0)break;
	}
	printf("%.2lf",ans);
}

第3关:汇率大师

300

  • 任务要求

描述

小明热衷于炒汇率,假设现在给你A币、B币、C币....等各个币种的兑换关系以及汇率,给你A币本金,请你帮小明算出兑换成最后一个币种的价值的最大值(以A币的价值表示)和最佳兑换路线。

注意:当存在不同路径的最大价值相同时,取路径短的,不存在价值和路径长度相同的样例。

输入说明:

先输入本金N(0<N<10000), 再输入兑换关系数量M(0<M<100)和币种数量H(0<H<26),接下来输入M行,每行的前两项是数字表示的币种,后面一项是汇率。

为简化题目,这里的汇率,可以理解为倍率,统一用正小数表示,例如本金100A币的时候,0 1 1.5 就可以理解为A币可以兑换价值150A币的B币.(保留小数点2位)

样例:

1.

输入: 100 1 2 0 1 1.5 输出: 150.00 A->B 说明: 这里是本金100,一个关系和两个币种

2.

输入: 100 9 6 0 1 2 0 2 1 0 3 6 1 2 1 1 4 1 2 4 2 3 2 5 3 4 8 4 5 1

输出: 6000.00 A->D->C->E->F

本题考察图论-图的遍历。数据量较小,dfs爆搜。注意保存路径长度和路径。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int arr[1010];
int brr[1010];
vector<pair<int, double>> edges[30];
int n, m, h;
double maxRate;
int ansPath[110];
int cachePath[110];
bool vis[30];
int ansDeep = 9999;
void dfs(int u, double proRate, int deep) {
	cachePath[deep] = u;
	if (u == h - 1) {
		if (maxRate < proRate || (maxRate == proRate && ansDeep > deep)) {
			maxRate = proRate;
			ansDeep = deep;
			for (int i = 1; i <= deep; i++) {
				ansPath[i] = cachePath[i];
			}
		}
		return;
	}
	for (auto it : edges[u]) {
		int v = it.first;
		double rate = it.second;
		if (vis[v] == 0) {
			vis[v] = 1;
			dfs(v, proRate * rate, deep + 1);
			vis[v] = 0;
		}
	}
}

int main() {
	cin >> n >> m >> h;
	for (int i = 1; i <= m; i++) {
		int a, b;
		double c;
		cin >> a >> b >> c;
		edges[a].push_back({b, c});
		edges[b].push_back({a, 1 / c});
	}
	vis[0] = 1;
	dfs(0, 1, 1);
	cout.precision(2);
	cout << fixed << n*maxRate << endl;
	cout << "A";
	for (int i = 2; i <= ansDeep; i++) {
		cout << "->" << (char)(ansPath[i] + 'A');
	}

}

第4关:铠甲锻造

300

  • 任务要求

题目描述

一套铠甲的打造需要n种材料,编号为i的材料的坚硬度为ai(0<i<n),约定材料必须按照编号顺序依次放入冶炼炉,容量有限的冶炼炉同时最多只能容纳w个原料。但是我们可以在放入某个材料之前从冶炼炉种取出一些原料,取出的数量不能超过s个。

设: 编号为i的材料的耐久= 放入时冶炼炉内原料总数 * 材料坚硬度ai,铠甲的耐久为所有合成材料的耐久之和。

输入格式

line 1:3个整数n w s

line 2:n个整数 a1 … an


1 ≤ n ≤ 10^5 |ai| ≤ 10^7

输出格式

每行一个整数,为最大耐久度

输入输出样例

输入

 
  1. 5 3 3
  2. 1 3 2 4 5

输出

  1. 40

本题考察动态规划-01背包。考虑枚举将材料从锅中拿出的个数。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
long long a[5005];
long long dp[5005][5005];

int main() {
	int s, w, n;
	cin >> n >> w >> s;
	for (int i = 1; i <= n; ++i)cin >> a[i];
	memset(dp, 0xcf, sizeof(dp));
	dp[0][0] = 0;

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= w; ++j) {
			for (int k = 0; k <= s; ++k) {
				if (j + k - 1 <= w)
					dp[i][j] = max(dp[i][j], dp[i - 1][j + k - 1] + a[i] * j);
			}
		}
	}
	long long ans = -0x3f3f3f3f3f3f3f3f;
	for (int i = 1; i <= w; ++i) {
		ans = max(ans, dp[n][i]);
	}

	cout << ans;

}

第6关:乌鸦爱收集

300

  • 任务要求

题目背景

乌鸦Ozzy喜欢收集特殊的石头,今天的Ozzy也准备出门去收集喜欢的石头。

题目描述

Ozzy在小溪边饮水时,发现了溪边有一排特殊排列的石头,这些石头颜色分别为a1、a2、…、an,一共有 n 个,奥兹准备收集那些特殊的石头。

满足这些条件的这些条件的会被Ozzy认为特殊的石头:在给定的区间,并且在该区间内与它颜色相同石头的个数,与在该区间外这种颜色的石头的数量差 ≤给定常数K

请回答Ozzy的m个提问:区间[l,r]中有多少不同颜色的特殊石头

输入格式

line 1:正整数n m k

line 2:n 个正整数,为石头的颜色 ti

之后 m 行,正整数l r


0< l ≤ r < n

1 ≤ n ≤ 10^5 1 ≤ m ≤ 10^3 1 ≤ k ≤ 10^2

输出格式

m行,每个各一个整数表示询问的结果

输入输出样例

输入

 
  1. 6 9 10
  2. 13 11 1 12 11 11
  3. 4 4
  4. 4 4
  5. 0 0
  6. 3 5
  7. 2 5
  8. 1 4
  9. 2 4
  10. 5 5
  11. 3 3

输出

 
  1. 1
  2. 1
  3. 0
  4. 3
  5. 3
  6. 4
  7. 3
  8. 1
  9. 1

本题考察树状数组与扫描线这对经典cp的使用。需要用到扫描线思想,然后配合树状数组的区间修改和区间查询,以便实现离线处理询问,最后输出答案。当然也可以直接暴力求解。

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int num[100010][100];
int flag[101];
int main()
{
	int n,m,k;
	memset(flag,0,sizeof(flag));  
	scanf("%d %d %d",&n,&m,&k);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		flag[a[i]]=1;		
		for(int j=1;j<=100;j++)
		{
			num[i][j]=num[i-1][j];
		}
		num[i][a[i]]++;
	}
	while(m--)
	{
		int l,r;
		int temp=0;
		scanf("%d %d",&l,&r);
		for(int i=1;i<=100;i++)
		{
			if(abs((num[r][i]-num[l-1][i])-(num[n][i]-num[1][i]))<=k&&num[r][i]-num[l-1][i]!=0)
			{
				temp++;
			}
		}
		
		printf("%d\n",temp);
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SQ_ZYX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值