[解题报告] CSDN竞赛第四期
Posted lijiancheng0614
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[解题报告] CSDN竞赛第四期相关的知识,希望对你有一定的参考价值。
CSDN竞赛第四期 解题报告
1. 小玉家的电费
题目
夏天到了,各家各户的用电量都增加了许多,相应的电费也交的更多了。小玉家今天收到了一份电费通知单。小玉看到上面写:据闽价电[2006]27号规定,月用电量在150千瓦时及以下部分按每千瓦时0.4463元执行,月用电量在151~400千瓦时的部分按每千瓦时0.4663元执行,月用电量在401千瓦时及以上部分按每千瓦时0.5663元执行; 小玉想自己验证一下,电费通知单上应交电费的数目到底是否正确呢。请编写一个程序,已知用电总计,根据电价规定,计算出应交的电费应该是多少。
输入描述:
输入一个整数,表示用电总计(单位以千瓦时计),不超过10000。
输出描述:
输出一个数,保留到小数点后1位(单位以元计,保留到小数点后一位)。
示例:
输入
267
输出
121.5
解题报告
模拟题
#include <iostream>
#include <cstdio>
using namespace std;
void solve(int n)
double s = 0;
if (n <= 150)
s = n * 0.4463;
else if (n <= 400)
s = 150 * 0.4463;
s += (n - 150) * 0.4663;
else
s = 150 * 0.4463;
s += (400 - 150) * 0.4663;
s += (n - 400) * 0.5663;
printf("%.1f\\n", s);
int main()
int n;
scanf("%d", &n);
solve(n);
return 0;
2. 单词逆序
题目
对于一个字符串,请设计一个算法,只在字符串的单词间做逆序调整,也就是说,字符串由一些由空格分隔的部分组成,
你需要将这些部分逆序。 给定一个原字符串A,请返回逆序后的字符串。例,输入”I am a boy!“输出”boy! a am I“
输入描述:
输入一行字符串str。(1 <= strlen(str) <= 10000)
输出描述:
返回逆序后的字符串
示例:
输入
It’s a dog!
输出
dog! a It’s
解题报告
模拟题,注意用 gets
会出现 warning,而答案判断包含了 warning 信息会提示答案错误
#include <iostream>
#include <string>
using namespace std;
string a;
void solve()
int j = a.length() - 1;
for (int i = j; i >= -1; --i)
if (a[i] == ' ' || i == -1)
if (i != j)
for (int k = i + 1; k <= j; ++k)
printf("%c", a[k]);
printf(" ");
--i;
j = i;
printf("\\n");
int main()
getline(cin, a);
solve();
return 0;
3. 小Q整数分割
题目
小Q决定把一个整数n,分割为k个整数。
每个整数必须大于等于1。
小Q有多少方案。
输入描述:
输入整数n,k。(1 <= n, k<= 100)
输出描述:
输出方案数。答案对1e9+7取模。
示例:
输入
3 3
输出
1
解题报告
动态规划。
设 f[i][j] 表示将 i 分割为 j 个整数的方案数,则
f
[
i
]
[
j
]
=
f
[
i
−
1
]
[
j
−
1
]
+
f
[
i
−
j
]
[
j
]
,
if 2 <= j <= i
1
,
if i = 1 or j = 1
0
,
if j > i
f[i][j] = \\begincases f[i - 1][j - 1] + f[i - j][j], & \\textif 2 <= j <= i \\\\ 1, & \\textif i = 1 or j = 1 \\\\ 0, & \\textif j > i \\endcases
f[i][j]=⎩
⎨
⎧f[i−1][j−1]+f[i−j][j],1,0,if 2 <= j <= iif i = 1 or j = 1if j > i
其中
f
[
i
−
1
]
[
j
−
1
]
f[i - 1][j - 1]
f[i−1][j−1] 表示第
j
j
j 个数为
1
1
1,剩下
i
−
1
i - 1
i−1 分割为
j
−
1
j - 1
j−1 个整数时的方案数;
f
[
i
−
j
]
[
j
]
f[i - j][j]
f[i−j][j] 表示第
j
j
j 个数不为
1
1
1,即所有
j
j
j 个位置均放
1
1
1 时,剩下
i
−
j
i - j
i−j 再分割为
j
j
j 个整数时的方案数。
注:由于题目设置问题,数据中有超过 100 范围的数,故需要进行判断,否则容易报数组越界的错误。希望后续平台能把报错信息也提供一下,方便排查。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
#define N 1005
#define MOD 1000000007
ll f[N][N];
void solve(int n, int k)
if (n > 1000 || k > 1000)
printf("0\\n");
return;
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= i; ++j)
if (i == j || j == 1)
f[i][j] = 1;
else
f[i][j] = (f[i - 1][j - 1] + f[i - j][j]) % MOD;
printf("%lld\\n", f[n][k]);
int main()
int n, k;
scanf("%d%d", &n, &k);
solve(n, k);
return 0;
4. 新型美丽数列
题目
定义美丽数列A:
- 数列中相邻的数越是靠内相对大小加一,a[2]=a[1]+1,a[n-2]=a[n-1]+1…
- 距离边缘距离相等的数的大小相等:a[0] = a[n-1],a[1] = a[n-2]…
通过修改最小的数字使得给定数列变成美丽数列。
修改后的值必须仍是正整数。
输入描述:
第一行输入整数n。(1<=n<=1000)表示数列的大小。
第二行输入n个整数。
输出描述:
输出最小修改。
输入样例:
3
1 1 1
输出样例:
1
解题报告
由于第 3 题范围问题花了一些时间排查,这道题快速看完题后就写了起来,没想到理解错题意了。
以为是修改任意的数字使得数列成为先升后降的数列(如 2 3 4 3 2
或 2 3 4 4 3 2
),因此直接遍历每个数字,模拟其最终的数列算出修改次数即可。
赛后才发现需要修改当前数列中最小的数字。由于没有找到赛后能提交练习的地方,这里就不提供代码了。
以上是关于[解题报告] CSDN竞赛第四期的主要内容,如果未能解决你的问题,请参考以下文章