第1关:101_求最长的公共字符串
任务描述
系统会给出两个字符串,你需要获取到这两个数据(方法同从键盘获取一样),并找到他们最长的公共字符串,并且将他们的长度打印。
样例
输入ABCD
,CBCE
返回 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
位顾客那里,我们收取3
张5
元。 第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
- 任务要求
- 评论
任务描述
系统输入一个整数x
,x>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
次灌水的时候,可以灌入1
至num[i-1]
升水。
问有多少种灌满水的方法?答案可能很大,答案对1e9+7
取模。
• 1 <= n <= 10^6
• 1 <= num[i] <=10^6
样例
给出n=2
,num=[2,2]
,返回2
。
解释:
可以倒入2
次1
升的水,也可以在第1
次倒入2
升的水。
给出n=3
,num=[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
颜色1
, 2 + 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=2
,Z=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]);
}
}