[解题报告] 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[i1][j1]+f[ij][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[i1][j1] 表示第 j j j 个数为 1 1 1,剩下 i − 1 i - 1 i1 分割为 j − 1 j - 1 j1 个整数时的方案数;
f [ i − j ] [ j ] f[i - j][j] f[ij][j] 表示第 j j j 个数不为 1 1 1,即所有 j j j 个位置均放 1 1 1 时,剩下 i − j i - j ij 再分割为 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:

  1. 数列中相邻的数越是靠内相对大小加一,a[2]=a[1]+1,a[n-2]=a[n-1]+1…
  2. 距离边缘距离相等的数的大小相等: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 22 3 4 4 3 2),因此直接遍历每个数字,模拟其最终的数列算出修改次数即可。
赛后才发现需要修改当前数列中最小的数字。由于没有找到赛后能提交练习的地方,这里就不提供代码了。

以上是关于[解题报告] CSDN竞赛第四期的主要内容,如果未能解决你的问题,请参考以下文章

CSDN 竞赛第四期 - 解题心得

CSDN 竞赛第四期 - 解题心得

[解题报告] CSDN竞赛第22期

[解题报告] CSDN竞赛第22期

[解题报告] CSDN竞赛第21期

[解题报告] CSDN竞赛第21期