【CSDN竞赛第13期】75分简要题解

目录

  • 1、陶陶摘苹果(水题)
    • 题目
    • 题解
    • 代码(100%)
  • 2、硬币的面值(贪心)
    • 题目
    • 题解
    • 比赛时代码(90%)
  • 3、公司新表(简单数学)
    • 题目
    • 题解
    • 比赛时代码(90%)
  • 4、小豚鼠排排坐(组合数学?)
    • 题目
    • 题解(未验证)
    • 代码(20%)

1、陶陶摘苹果(水题)

题目

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 10 个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个 30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。 现在已知 10 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。

题解

直接比较大小和计数。

代码(100%)

#include 
#include 

int solution(int arr[10], int max_tourch_height) {
    int result;
// TODO:
    result = 0;
    for (int i = 0; i < 10; i++) {
        if (arr[i] <= 30 + max_tourch_height) {
            result++;
        }
    }
    return result;
}

int main() {
    int arr[10];
    int max_tourch_height;
    for (int i = 0; i < 10; i++) {
        std::cin >> arr[i];
    }
    std::cin >> max_tourch_height;
    int result = solution(arr, max_tourch_height);
    std::cout << result << std::endl;
    return 0;
}

2、硬币的面值(贪心)

题目

小A有n枚硬币,现在要买一样不超过m元的商品,他不想被找零,同时又不想带太多的硬币,且硬币可以重复,现在已知这n枚硬币的面值,请问最少需要多少枚硬币就能组合成所有可能(即能组合成1-m任意之间的数字)的价格?

题解

枚举需满足金额1~m,当已选中硬币可以满足1~x元商品时,新增一枚v硬币,必然可以满足1~(x+v)。

直观感觉用的硬币面值越大,个数一般就越少。因此每当枚举发现无法满足,就用小于等于当前枚举值的最大面值硬币补足。

应该是这样的,未验证。比赛时想错了,不应该补足差值。

比赛时代码(90%)

#include 
#include 
#include 
#include 
#include

using namespace std;

// 1 2 4 5 5 5 5 5
void solution(int n, int m, std::vector<int> &vec) {
    sort(vec.begin(), vec.end());
    if (vec[0] != 1) {
        cout << "No answer!!!" << endl;
        return;
    }
    int sum = 0;
    int result = 0;
    for (int i = 0; i < (int) vec.size(); i++) {
        int aim = min(vec[i] - 1, m);
        if (sum < aim) {
            int add = (aim - sum + vec[i - 1] - 1) / vec[i - 1];
            result += add;
            sum += add * vec[i - 1];
        }
    }
    if (sum < m) {
        result += (m - sum + vec.back() - 1) / (vec.back());
    }
    cout << result << endl;
}

int main() {
    int n;
    int m;
    std::vector<int> vec;
    std::cin >> n;
    std::cin >> m;
    std::string line_0, token_0;
    getline(std::cin >> std::ws, line_0);
    std::stringstream tokens_0(line_0);
    while (std::getline(tokens_0, token_0, ' ')) {
        vec.push_back(std::stoi(token_0));
    }
    solution(n, m, vec);
    return 0;
}

3、公司新表(简单数学)

题目

公司里为了凸显公司的特性。 安装了一个n进制表。 已知新的表的时间是”H:M”。 时间合法的定义为H<=23 &&M<=59。 时间有多少种进制定义的方式,依次打印出来。 如果有无数种解输出”-1”,不存在输出”0”。

题解

去除前导零的读取H和M。
如果H和M仅有一位,因为无关进制,答案必为0或-1。
否则H或M至少有一个不只一位,枚举可能的进制,检查是否满足,累计答案。
比赛时大概是晚上犯迷糊忘了,应至少从2枚举到59,因为可能M有2位,但H仅1位。

比赛时代码(90%)

#include 
#include 
#include 
#include 

using namespace std;

int charToInt(char ch) {
    if (ch >= 'a' && ch <= 'z') {
        return ch - 'a' + 10;
    } else if (ch >= 'A' && ch <= 'Z') {
        return ch - 'A' + 10;
    }
    return ch - '0';
}

std::vector<int> solution(std::string m) {
    std::vector<int> result;
// TODO:
    string a, b;
    int p = -1;
    for (int i = 0; i < (int) m.length(); i++) {
        if (m[i] != ':') {
            if (p == -1) {
                if (a != "" || m[i] != '0') {
                    a = a + m[i];
                }
            } else {
                if (b != "" || m[i] != '0') {
                    b = b + m[i];
                }
            }
            continue;
        }
        p = i;
    }
    if (a == "") {
        a = "0";
    }
    if (b == "") {
        b = "0";
    }
    if (p == -1) {
        result.push_back(0);
        return result;
    }
    if ((int) a.length() == 1 && (int) b.length() == 1) {
        if (charToInt(a[0]) > 23 || charToInt(b[0]) > 59) {
            result.push_back(0);
            return result;
        }
        result.push_back(-1);
        return result;
    }
    // !此处应枚举到59,因为可能M有2位,但H仅1位
    for (int zhi = 2; zhi <= 23; zhi++) {
        bool ok = true;
        int aa = 0;
        for (int i = 0; i < (int) a.length() && ok; i++) {
            int ai = charToInt(a[i]);
            aa = aa * zhi + ai;
            ok = ok && ai < zhi;
        }
        int bb = 0;
        for (int i = 0; i < (int) b.length() && ok; i++) {
            int bi = charToInt(b[i]);
            bb = bb * zhi + bi;
            ok = ok && bi < zhi;
        }
        ok = ok && aa <= 23 && bb <= 59;
        if (ok) {
            result.push_back(zhi);
        }
    }
    if ((int) result.size() == 0) {
        result.push_back(0);
    }
    return result;
}

int main() {
    std::string m;
    getline(std::cin, m);;
    std::vector<int> result = solution(m);
    for (auto it = result.begin(); it != result.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    return 0;
}

4、小豚鼠排排坐(组合数学?)

题目

小艺酱买了一个由一排排格子组成的小房子nm,她想让k个小豚鼠每个小豚鼠都有自己的格子。
但是为了不浪费空间,她想要最边角的一圈2
(n+m-2)每行每列的格子都有一个小豚鼠居住。
具体来说,假设这k只小豚鼠的格子坐标为(x1, y1), (x2, y2),…,(xk, yk),则需要满足存在1 小艺酱想知道自己有多少种方案安排小豚鼠。

题解(未验证)

没完全看明白题意……

“有一个”应该是指至少一个。似乎应该理解为不同豚鼠是不同的?

格子有3类:4角、上下左右和内部。
相当于一共4个要求,不考虑重复放4角一次可以满足2个,放上下左右可以满足一个,放中间一个也满足不了。
按4角、上下左右和内部的顺序枚举。

比赛时没时间了,写的特判可能有问题。如果连2个豚鼠都没有显然无法满足,如果恰有2个应该有2种方案。

代码(20%)

#include 
#include 
#include 
#include 

int xuanze(int m, int n) {
}

int solution(std::vector<int> &vec) {
    int result;
// TODO:
    result = 0;
    int n = vec[0], m = vec[1], k = vec[2];
    if (k < 2) {
        return 0;
    } else if (k == 2) {
        return 1;
    }
    return result;
}

int main() {
    std::vector<int> vec;
    std::string line_0, token_0;
    getline(std::cin >> std::ws, line_0);
    std::stringstream tokens_0(line_0);
    while (std::getline(tokens_0, token_0, ' ')) {
        vec.push_back(std::stoi(token_0));
    }
    int result = solution(vec);
    std::cout << result << std::endl;
    return 0;
}

你可能感兴趣的:(ACM,C++,acm竞赛,算法,c++)