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

第1关:101_求最长的公共字符串

任务描述

系统会给出两个字符串,你需要获取到这两个数据(方法同从键盘获取一样),并找到他们最长的公共字符串,并且将他们的长度打印。


样例

输入ABCDCBCE 返回 2


测试说明

平台会对你编写的代码进行测试:


测试输入: ABCD CBCE


预期输出: 2


开始你的任务吧,祝你成功!

暴力冲即可。

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<map>
#include<cstring>
#define int long long
using namespace std;
typedef long long ll;
const int N = 200000;
int arr[N + 10];
int nex[200000];
int32_t main() {
	string s1, s2;
	cin >> s1 >> s2;
	int ans = 0;
	int len1 = s1.length();
	int len2 = s2.length();
	for (int i = 0; i < len1; i++) {
		for (int j = 0; j < len2; j++) {
			int ii = i, jj = j;
			int cnt = 0;
			while (ii <= len1 && jj <= len2 && s1[ii] == s2[jj]) {
				cnt++;
				ii++;
				jj++;
			}
			ans = max(ans, cnt);
		}
	}
	cout << ans << endl;
}

第2关:102饮料水

200

  • 任务要求
  • 评论

任务描述

在湘大xx奶茶店夏天推出了新的饮料价格为5元。 很多学生都要买饮料,每个学生一次只买一个。 然后给你人民币5元、10元或20元。 之后你给每个买了饮料的学生找零。 最初你这里没有钱(当第一个学生拿10元给你你就没办法找零钱)。 如果你能成功找零,返回true,否则返回false


样例

输入: 5 5 5 10 20 输出: true

解释: 前3位顾客那里,我们收取35元。 第4位顾客那里,我们收取一张10元,并返还5元。 第5位顾客那里,我们找还一张10元和一张5元。 因为你成功的给每个人找零了,所以我们输出true


测试说明

平台会对你编写的代码进行测试:

测试输入: 5 5 5 10 20

预期输出: true


测试输入: 10 10

预期输出: false


开始你的任务吧,祝你成功!

本题考察分支结构。

注意统计5元和10元钱的个数。

#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 = 200000;
int arr[N + 10];
int nex[200000];
int tong[120];
int32_t main() {
	int five = 0;
	int ten = 0;
	int num;
	bool flag = 1;
	while (cin >> num){
		if (num == 5) five++;
		else if (num == 10) {
			if (five >= 1) {
				five-=1;
				ten+=1;
			}else flag=0;
		} else if (num == 20) {
			if (five >= 1 && ten >= 1) {
				five--;
				ten--;
			} else if (five >= 3) {
				five -= 3;
			} else flag = 0;
		}
	}
	if (flag) puts("true");
	else puts("false");
}

第3关:103_搬砖头

200

  • 任务要求
  • 评论

任务描述

工地有n块砖头需要搬运,但由于重量限制,每次只能搬1块或者2块,你能帮工地计算下能有多少种不同的搬运方法吗?


样例

比如n=3,1+1+1=1+2=2+1=3,共有3种不同的方法。·


测试说明

平台会对你编写的代码进行测试:

测试输入: 3

预期输出: 3


开始你的任务吧,祝你成功!

本题考察基本递推模型。

dp[n]=dp[n-1]+dp[n-2];

#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 = 200000;
int arr[N + 10];
int nex[200000];
int tong[120];
int32_t main() {
	int n;
	cin >> n;
	if (n == 1) puts("1");
	else if (n == 2) puts("2");
	int a = 1, b = 2;
	n -= 2;
	while (n--) {
		int c = a + b;
		a = b;
		b = c;
	}
	cout << b << endl;
}

第4关:201_新的数

600

  • 任务要求
  • 评论

任务描述

这里我们定义一个新的数:对于一个正整数x,再将x每个数位的平方和赋值给x,重复上一步,最后这个数等于1。 你需要写程序判断一个数符不符合这个定义。 如果无限循环但始终变不到1,则输出NO。 如果可以变为1,那么这个数符合定义则输出YES

样例

19 就符合定义。

1^2 + 9^2 = 82 8^2 + 2^2 = 68 6^2 + 8^2 = 100 1^2 + 0^2 + 0^2 = 1

测试说明

平台会对你编写的代码进行测试:

测试输入:19 预期输出:YES


开始你的任务吧,祝你成功!

本题考察枚举。

暴力冲即可。

#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 = 200000;
int arr[N + 10];
int nex[200000];
int tong[120];
int32_t main() {
	int n;
	cin >> n;
	int cnt = 0;
	while (n != 1 && cnt <= 100) {
		cnt++;
		int sum = 0;
		while (n) {
			int cache = n % 10;
			n /= 10;
			sum += cache * cache;
		}
		n = sum;
	}
	if (cnt < 100) puts("YES");
	else puts("NO");

}

第5关:202_幸运数

600

  • 任务要求
  • 评论

任务描述

系统输入一个整数xx>0。 你需要找到一个数,使它的每一位的数字相乘之后的积等于x。 如果没有答案,则返回0;不超过32位整数。 如果有多个答案,返回最小的那个。


样例

给定 x = 48, 返回 68。 给定 a = 15, 返回 35


测试说明

平台会对你编写的代码进行测试:


测试输入: 48


预期输出: 68


开始你的任务吧,祝你成功!

本题考察枚举。

暴力冲即可。

#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 = 200000;
int arr[N + 10];
int nex[200000];
int tong[120];
int32_t main() {
	int n;
	cin >> n;
	if (n == 1) puts("1");
	else {
		for (int i = 1; i <= 1000000; i++) {
			int cache = i;
			int num=1;
			while (cache) {
				int factor=cache%10;
				num*=factor;
				cache/=10;
			}
			if(num==n){
				cout<<i<<endl;
				break;
			}
		}
	}


}

第6关:203 拆开正整数n

600

  • 任务要求
  • 评论

任务描述

给定一个正整数n,找出k个数x1,x2...xn(n>=2)。使得x1+x2+..xn=n,并且使得x1*x2...*xn的值最大。返回这个最大值max


样例

给定 n = 2 打印 1 (2 = 1 + 1)

给定 n = 10 打印 36 (10 = 3 + 3 + 4)


测试说明

平台会对你编写的代码进行测试:

测试输入: 10

预期输出: 36


开始你的任务吧,祝你成功!

本题考察贪心。

当数位的和确定时,且数位个数确定,越平均,乘积越大。可以用均值不等式证明。

#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 = 200000;
int arr[N + 10];
int nex[200000];
int tong[120];
int32_t main() {
	int n;
	cin >> n;
	if (n == 1) puts("1");
	else {
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			int cache=1;
			int num=n/i;
			if(num>=10) continue;
			int cnt=n%i;
			int tt=cnt;
			while(tt--)
			{
				cache*=num+1;
			}
			
			cnt = i-cnt;
			while(cnt--)
			{
				cache*=num;
			}
			ans=max(ans,cache);
		}
		cout<<ans<<endl;
	}
}

第7关:204_蓄水池

600

  • 任务要求
  • 评论

任务描述

工地有一个n升蓄水池,现在需要将它灌满水(不能溢出),当第i次灌水的时候,可以灌入1num[i-1]升水。

问有多少种灌满水的方法?答案可能很大,答案对1e9+7取模。

1 <= n <= 10^61 <= num[i] <=10^6


样例

给出n=2num=[2,2],返回2

解释:

可以倒入21升的水,也可以在第1次倒入2升的水。

给出n=3num=[3,2,1],返回4

解释:

方案一:第1次倒入3升的水。 方案二:第1次倒入1升的水,第2次倒入2升的水。 方案三:第1次倒入2升的水,第2次倒入1升的水。 方案四:第1次倒入1升的水,第2次倒入1升的水,第3次倒入1升的水。


测试说明

平台会对你编写的代码进行测试:

测试输入: 3 3 2 1

预期输出: 4


开始你的任务吧,祝你成功!

本题考察带限制条件的背包。或者我应该叫它求出连续阶段,的每一阶段,能到达终点的方案数的总和。很像分组背包???

第n次倒水的方案数,务必要从第n-1次进行转移。

总方案数,等于每次倒水完毕后,能到终点的方案数的和。

dp[i][j]代表连续倒了i次水后,水量能到j的方案数。

#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 = 2000;
int dp[2][N + 10];
int num[N + 10];

int nex[200000];
int tong[120];
int32_t main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> num[i];
	}
	dp[0][0] = 1;
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		int p = i & 1;
		for (int j = 1; j <= num[i]; j++) {
			for (int k = n; k - j >= i - 1; k--) {
				dp[p][k] += dp[p ^ 1][k - j];
				dp[p][k] %= 1000000007;
			}
		}
		ans += dp[p][n];
		ans %= 1000000007;
		for (int i = 1; i <= n; i++) {
			dp[p ^ 1][i] = 0;
		}
	}
	cout << ans;
}

第8关:205_背包

600

  • 任务要求
  • 评论

任务描述

又快到了寒假时间,说到寒假,免不了出去玩耍,小蒋今天要去郊游,她想带点零食去,但是她的包包大小有限,所以她需要在n个零食中挑选若干零食装入包包,最多能装多满?假设包包的大小为m,每袋零食的大小为A[i]


样例

如果有4个零食大小是[2, 3, 5, 7]。 如果包包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。 如果包包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。


测试说明

平台会对你编写的代码进行测试:

测试输入: 11 2 3 5 7

预期输出: 10


开始你的任务吧,祝你成功!

本题考察01背包。

dp[i][j]表示考虑完第i个物品后,背包的填装量能否到达j。

如果dp[i-1][j-num[i]]为1,说明我可以再放入一个物品i,那么有dp[i][j]=1。

#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 = 200000;
int dp[N + 10];
int num[N + 10];

int nex[200000];
int tong[120];
int32_t main() {
	int v;
	cin >> v;
	int n = 0;
	int cache;
	while (cin >> cache) {
		num[++n] = cache;
	}
	dp[0] = 1;
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = v; j >= num[i]; j--) {
			if (dp[j - num[i]]) {
				dp[j] = 1;
				ans = max(ans, j);
			}
		}
	}
	cout << ans << endl;

}

第9关:301_粉刷匠的难题

600

  • 任务要求
  • 评论

任务描述

粉刷匠遇到了一个难题:有n根柱子排成一条直线,需要给柱子涂上颜色,现在共有k种颜色,每根柱子涂不同颜色的费用不同。并且要求相邻柱子颜色不同。

你能帮他计算最小的支出费用吗?

费用通过一个n*k 的矩阵给出,比如cost[0][0]表示柱子0涂颜色0的费用,cost[1][2]表示柱子1涂颜色2的费用。


样例

costs = [ [ 14 , 2 , 11 ], [ 11 , 14 , 5 ], [ 14 , 3 , 10 ] ]

return 10

柱子0颜色1, 柱子1颜色2, 柱子2颜色12 + 5 + 3 = 10


测试说明

平台会对你编写的代码进行测试:

测试输入: 3 3 14 2 11 11 14 5 14 3 10

预期输出: 10


开始你的任务吧,祝你成功!

本题考察动态规划。贪心决策加递推。

dp[i][j]表示染色了前i根柱子,第i根柱子的颜色为j,时,所需的最小费用。

#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;
int 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, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> tu[i][j];
		}
	}

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			int cache = 123456789;
			for (int k = 1; k <= m; k++) {
				if (k != j) {
					cache = min(cache, dp[i - 1][k]);
				}

			}
			dp[i][j] = cache + tu[i][j];
		}
	}

	int cache = 987654321;

	for (int i = 1; i <= m; i++) {
		cache = min(cache, dp[n][i]);
	}
	cout << cache;
}

第10关:401_小明抛骰子

600

  • 任务要求
  • 评论

任务描述

小明他抛了n个骰子,抛出来之后显示的数是x1,x2,x3...xn

Z=x1+x2..+xn。(比如抛两个骰子 ,显示2,5。那么n=2Z=7

给定骰子个数n,计算出所有有几率出现的Z值以及他出现的可能性(几率)。

  • 概率用double类型,保留6位小数。

编程要求

抛出n个骰子,抛出来之后显示的数是x1,x2,x3...xn

Z=x1+x2..+xn

计算出所有Z值以及他出现的可能性(几率)。

测试说明

平台会对你编写的代码进行测试:

测试输入:1

预期输出: 1 0.166667 2 0.166667 3 0.166667 4 0.166667 5 0.166667 6 0.166667


开始你的任务吧,祝你成功!

此题考察动态规划,普通线性DP。

dp[i][j]表示,前i个骰子的点数和为j的可能性。

dp[i][j]=dp[i-1][j-1]*1/6+dp[i-1][j-2]*1/6+dp[i-1][j-3]*1/6+dp[i-1][j-4]*1/6+dp[i-1][j-5]*1/6+dp[i-1][j-6]*1/6;(因为当前骰子的1,2,3,4,5,6的取值概率均为1/6,当然你应该保证j-6>=0)

#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;
	dp[0][0] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = i * 6; j >= i; j--) {
			for (int k = 1; k <= 6 && j - k >= i - 1; k++) {
				dp[i][j] += dp[i - 1][j - k] * 1 / 6;
			}
		}
	}
	for (int i = n; i <= n * 6; i++) {
		printf("%d %.6lf\n", i, dp[n][i]);
	}


}

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SQ_ZYX

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

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

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

打赏作者

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

抵扣说明:

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

余额充值