zoukankan      html  css  js  c++  java
  • 洛谷训练新手村之“BOSS战入门综合练习2”题解

    P1426 小鱼会有危险吗

    题目链接:https://www.luogu.com.cn/problem/P1426
    题目大意:
    有一次,小鱼要从A处沿直线往右边游,小鱼第一秒可以游7米,从第二秒开始每秒游的距离只有前一秒的98%。有个极其邪恶的猎人在距离A处右边s米的地方,安装了一个隐蔽的探测器,探测器左右x米之内是探测范围。一旦小鱼进入探测器的范围,探测器就会在这一秒结束时把信号传递给那个猎人,猎人在一秒后就要对探测器范围内的水域进行抓捕,这时如果小鱼还在这范围内就危险了。也就是说小鱼一旦进入探测器范围,如果能在下1秒的时间内马上游出探测器的范围,还是安全的。现在给出s和x的数据,请你判断小鱼会不会有危险?如果有危险输出'y',没有危险输出'n'。
    解题思路:
    一直循环路程的移动一直到位移 \(\ge\) S-x,然后再移动 1 秒,判断是否 \(\gt\) S+x 即可。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    double S, s, x, v = 7;
    bool check() {
        while (s < S-x) {
            s += v;
            v *= 0.98;
        }
        s += v;
        return s > S+x;
    }
    int main() {
        cin >> S >> x;
        puts( check() ? "n" : "y" );
        return 0;
    }
    

    P1464 Function

    题目链接:https://www.luogu.com.cn/problem/P1464
    题目大意:
    求一个递归函数。
    解题思路:
    有很多重叠子问题,需要用到备忘录(记忆化搜索)。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    bool vis[22][22][22];
    long long f[22][22][22];
    long long w(long long a, long long b, long long c) {
        if (a <= 0 || b <= 0 || c <= 0) return 1LL;
        if (a > 20 || b > 20 || c > 20) return w(20, 20, 20);
        if (vis[a][b][c]) return f[a][b][c];
        vis[a][b][c] = true;
        if (a < b && b < c) f[a][b][c] = w(a,b,c-1) + w(a,b-1,c-1) - w(a,b-1,c);
        else f[a][b][c] = w(a-1,b,c) + w(a-1,b-1,c) + w(a-1,b,c-1) - w(a-1,b-1,c-1);
        return f[a][b][c];
    }
    int main() {
        long long a, b, c;
        while (~scanf("%lld%lld%lld", &a, &b, &c) && !(a==-1 && b==-1 && c==-1)) {
            printf("w(%lld, %lld, %lld) = %lld\n", a, b, c, w(a, b, c));
        }
        return 0;
    }
    

    P1014 Cantor表

    题目链接:https://www.luogu.com.cn/problem/P1014
    题目大意:
    找到Cantor表的第N项。
    解题思路:
    枚举找。
    发掘规律:
    我们设当前的分子是 \(a\) ,分母是 \(b\) ,则:

    • 如果 \(a+b\) 是偶数:
      • 如果 \(a \lt 1\) ,则 \(a=a-1; b=b+1\)
      • 否则,\(b=b+1\)
    • 如果 \(a+b\) 是奇数:
      • 如果 \(b \lt 1\) ,则 \(a=a+1; b=b-1\)
      • 否则,\(a=a+1\)

    一开始 \(a=b=1\) ,按照此规律循环 \(N-1\) 次即可。

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int n, a = 1, b = 1;
    int main() {
        cin >> n;
        while (-- n) {
            if ( (a+b) % 2 == 0 ) {
                if (a > 1) a --, b ++;
                else b ++;
            }
            else {
                if (b > 1) a ++, b --;
                else a ++;
            }
        }
        cout << a << "/" << b << endl;
        return 0;
    }
    

    P1022 计算器的改良

    题目链接:https://www.luogu.com.cn/problem/P1022
    题目大意:解一元一次方程。
    解题思路:
    这道题目较为繁琐的是对于输入的处理。
    我一开始是处理字符串使得变成多个“符号”+“数字”+“a/b”的形式,规范化了字符串格式之后,我再使用 stringstream 来处理。
    然后处理起来有一些细节要处理,有点伤脑筋,脑细胞死掉不少囧。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    string s;
    char cc;
    int main() {
        cin >> s;
        bool flag = false;
    
        for (int i = 0; i < s.length(); i ++) {
            if (isalpha(s[i])) {
                cc = s[i];
                s[i] = 'a';
            }
            if (s[i] == '=') { flag = true; }
            else if (flag && s[i] == '+') s[i] = '-';
            else if (flag && s[i] == '-') s[i] = '+';
        }
        for (int i = 0; i < s.length(); i ++) {
            if (s[i] == '=') {
                if (s[i+1] != '+' && s[i+1] != '-') s[i] = '-';
                else s = s.substr(0, i) + s.substr(i+1);
                break;
            }
        }
        if (s[0] == 'a') s = "1" + s;
        while (true) {
            int idx = -1;
            int len = s.length();
            for (int i = 1; i < len; i ++) {
                if (s[i] == 'a' && !isdigit(s[i-1])) {
                    idx = i;
                    break;
                }
            }
            if (idx == -1) break;
            else s = s.substr(0, idx) + "1" + s.substr(idx);
        }
        while (true) {
            int idx = -1;
            int len = s.length();
            for (int i = 0; i < len; i ++) {
                if (isdigit(s[i]) && (i==len-1 || s[i+1]=='+' || s[i+1]=='-' )) {
                    idx = i;
                    break;
                }
            }
            if (idx == -1) break;
            else s = s.substr(0, idx+1) + "b" + s.substr(idx+1);
        }
        stringstream ss(s);
        char c;
        int num, a = 0, b = 0;
        while (ss >> num >> c) {
            if (c == 'a') a += num;
            else b += num;
        }
        double res = - (double) b / (double) a;
        printf("%c=%.3lf\n", cc, res);
    }
    

    P1307 数字反转

    题目链接:https://www.luogu.com.cn/problem/P1307
    题目大意:带符号数字翻转。
    解题思路:先取出符号,然后对数据进行翻转,最后如果一开始是负数再把符号加上。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    bool flag = false;
    int a, b;
    int main() {
        cin >> a;
        if (a < 0) { flag = true; a = -a; }
        while (a) {
            b = b * 10 + a % 10;
            a /= 10;
        }
        if (flag) b *= -1;
        cout << b << endl;
        return 0;
    }
    
  • 相关阅读:
    Generate Parentheses
    Length of Last Word
    Maximum Subarray
    Count and Say
    二分搜索算法
    Search Insert Position
    Implement strStr()
    Remove Element
    Remove Duplicates from Sorted Array
    Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/quanjun/p/11954123.html
Copyright © 2011-2022 走看看