CUMTOJ算法作业一

问题 A: 小雏鸟的成人式 2

题目描述

陶行知先生说:“我们要活的书,不要死的书 ”。
小雏鸟们从书上都是对的到现在能去伪存真的去使用书籍,证明你们长大了。总之就是要有自己的主见,自己的思考。
大白希望大家都能拿到一百分,所以对100这个数以及他的倍数很喜欢。
大白发现,从1开始,一定能找出一个序列从小到大排列,使得每一项都是 恰好能且仅能 被100整除D次。
请你编写程序,找到这个数列里第N个数。

输入

多行。每行输入两个整数,表示D和N,N范围[1,100],D范围[0,2]

输出

每行对应输入,给出一个符合题意的整数

样例输入

0 5
1 11
2 85

样例输出

5
1100
850000

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;
int main()
{
long long D, N;
while(cin >> D, cin >> N)
{
if(D == 0)
if(N == 100)
cout << 101 << endl;
else
cout << N << endl;
else if(D == 1)
if(N == 100)
cout << 10100 << endl;
else
cout << (N * 100) << endl;
else if(D == 2)
if(N == 100)
cout << 1010000 << endl;
else
cout << (N * 10000) << endl;
}
return 0;
}

问题 B: 小雏鸟的成人式 3

题目描述

陶行知先生说:“因为道德是做人的根本。根本一坏,纵然使你有一些学问和本领,也无甚用处。”
小雏鸟们需要时刻铭记在心,不管你长成什么样的的攻城狮,都必须三观正确。
涛涛轰这一天带着爱美酱来到了一个风景如画的地方游玩。艳阳高照,他俩玩的很尽兴,但是现在他们口渴了。
涛涛轰:“我要买饮料!”
店主:“我们这里有三种饮料,矿泉水1.5元一瓶,可乐2元一瓶,橙汁3.5元一瓶。”
涛涛轰:“好的,给我一瓶矿泉水。”
说完他掏出一张N元的大钞递给店主。
店主:“我忘了提醒你了,我们这里没有找客人钱的习惯的,多的钱我们都当小费收了的,嘿嘿。”
涛涛轰:“……”
涛涛轰环顾四周,就这一家商店,况且实在太渴了,看着脸热的粉扑扑的一头汗的爱美酱,就决定在这买了。不过涛涛轰想,与其把钱当小费送给他还不如自己多买一点饮料,反正早晚都要喝,但是要尽量少让他赚小费。
现在涛涛轰希望你能帮他计算一下,最少他要给店主多少小费。

输入

输入数据的第一行是一个整数T(1<=T<=100),代表测试数据的数量。然后是T行测试数据,每个测试数据只包含一个正整数N(1<=N<=10000),N代表小明手中钞票的面值,以分为单位。
注意:商店里只有题中描述的三种饮料。

输出

对于每组测试数据,请你输出小明最少要浪费多少钱给店主作为小费,以分为单位。

样例输入

2
900
250

样例输出

0
50

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int m, i, j, k;
for(m = 0; m < n; m++)
{
int max = 0;
int s;
cin >> s;
for(i = s / 350; i >= 0; i--)
{
for(j = (s - i * 350) / 200; j >= 0; j--)
{
for(k = (s - i * 350 - j * 200) / 150; k >= 0; k--)
{
int p = i * 350 + j * 200 + k * 150;
if(p > max)
max = p;
}
}
}
cout << s - max << endl;
}
return 0;
}

问题 E: 进制转换

题目描述

输入一个十进制正整数,然后输出它所对应的八进制数。

输入

输入一个十进制正整数n(1≤n≤106) 。

输出

输出n对应的八进制数,输出在一行。

样例输入

10

样例输出

12

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
int main()
{
int a, b, i[100], n = 1, k = 0;
cin >> a;
if(a >= 8)
{
while(a > 0)
{
i[n] = a % 8;
a = a / 8;
n++;
k++;
}
while(k >= 1)
{
cout << i[k];
k--;
}
}
else
{
b = a;
cout << b;
}
return 0;
}

问题 H: 求第k小

题目描述

给定n(1<=n<=1000000)个元素,求第k小数(1<=k<=n)。

输入

一组样例。第一行输入两个整数n和k。第二行输入n个不同的int范围内的数。

输出

输出一行,输出第k小数。

样例输入

5 2
1 5 3 2 4

样例输出

2

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
using namespace std;
int a[1000001];
int main()
{
void swap(int &a,int &b);
void select(int a[],int p,int r);
int partition(int a[], int p, int r);
int n, k;
cin >> n;
cin >> k;
for(int i = 0; i < n; i++)
cin >> a[i];
select(a, 0, n-1);
cout << a[k - 1] << endl;
return 0;
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}

int partition(int a[], int p, int r)
{
int x = a[r];
int middle = p;
int j;
for(j = p; j < r; j++)
{
if(a[j] < x)
{
if(j != middle)
swap(a[middle], a[j]);
middle++;
}
}
swap(a[middle], a[j]);
return middle;
}

void select(int a[],int p,int r)
{
if(p < r)
{
int q = partition(a, p, r);
select(a, p, q - 1);
select(a, q + 1, r);
}
}

问题 I: 沙子的质量

题目描述

设有N堆沙子排成一排,其编号为1,2,3,…,N(N< =300)。每堆沙子有一定的数量,可以用一个整数来描述,现在要将N堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有4堆沙子分别为1 3 5 2我们可以先合并1、2堆,代价为4,得到4 5 2又合并1,2堆,代价为9,得到9 2,再合并得到11,总代价为4+9+11=24,如果第二步是先合并2,3堆,则代价为7,得到4 7,最后一次合并代价为11,总代价为4+7+11=22;问题是:找出一种合理的方法,使总的代价最小。输出最小代价。

输入

第一行一个数N表示沙子的堆数N。 第二行N个数,表示每堆沙子的质量。 a[i]< =1000。

输出

合并的最小代价。

样例输入

4
1 3 5 2

样例输出

22

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
using namespace std;
const int maxn = 305;
int dp[maxn][maxn], sum[maxn], n;
int main()
{
int dfs(int l, int r);
cin >> n;
memset(dp, -1, sizeof(dp));
for (int i = 1; i <= n; ++i)
{
int x;
cin >> x;
sum[i] = sum[i - 1] + x;
}
cout << dfs(1, n) << endl;
return 0;
}
int dfs(int l, int r)
{
int min(int x, int y);
if(l == r)
return 0;
if(l + 1 == r)
return sum[r] - sum[l - 1];
if(dp[l][r] != -1)
return dp[l][r];
int ans = 2e9;
for(int i = l; i < r; ++i)
ans = min(ans, dfs(l, i) + dfs(i + 1, r));
ans += sum[r] - sum[l - 1];
dp[l][r] = ans;
return ans;
}
int min(int x, int y)
{
return x > y ? y : x;
}

问题 J: 最长公共子序列

题目描述

一个字符串A的子串被定义成从A中顺次选出若干个字符构成的串。如A=“cdaad” ,顺次选1,3,5个字符就构成子串” cad” ,现给定两个字符串,求它们的最长共公子串。

输入

第一行两个字符串用空格分开。两个串的长度均小于2000 。

输出

最长子串的长度。

样例输入

abccd aecd

样例输出

3

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>
using namespace std;
const int max_num = 2000;
int main()
{
int max(int x, int y);
string s1, s2;
int m, n, i, j;
cin >> s1;
cin >> s2;
m = s1.length();
n = s2.length();
int c[max_num][max_num] = { 0 };
for(i = 1; i <= m; i++)
{
for(j = 1; j <= n; j++)
{
if(s1[i - 1] == s2[j - 1])
c[i][j] = c[i - 1][j - 1] + 1;
else
c[i][j] = max(c[i - 1][j], c[i][j - 1]);
}
}
cout << c[m][n] << endl;
return 0;
}
int max(int x, int y)
{
return x > y ? x : y;
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。

×

喜欢就点赞,疼爱就打赏