每日一练16&17——C++完全数计算&&扑克牌大小&&杨辉三角的变形&&计算某字符出现次数


完全数计算

题目链接:

思路:

本题可以通过遍历每一个约数,求和,判断完全数。约数计算可以遍历sqrt(n)的范围。

代码:

#include<iostream>
using namespace std;
int main() {
    int num;
    cin >> num;
    int SUM_OF_NUM = 0;
    for (int ENUM = 1; ENUM <= num; ENUM++) {
        int sum = 0;
        for (int i = 1; i < ENUM; i++) {
            if (ENUM % i == 0) {
                sum += i;
            }
        }
        if (sum == ENUM) {
            SUM_OF_NUM++;
        }
    }
    cout << SUM_OF_NUM;
    return 0;
}

扑克牌大小

题目链接:

思路:

本题的题目意思是输入的只是这些类型中的一种,个子,对子,顺子(连续5张),三个,炸弹(四个)和对王。其实就是最多5张牌(顺子),最少1一张牌之间的比较。不存在其他情况。

  • 首先判断是否有对王。对王最大。
  • 然后由输入保证两手牌都是合法的,顺子已经从小到大排列,如果两手牌的数量相同那么就可以直接比较第一张牌即可。
  • 如果两手牌的数量不相同,一定是有炸弹和对王,对王我们最开始就比较了,炸弹就看哪手牌的数量是4,那么就哪手牌大。

代码:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

string FindMax(const string& line) {
    if (line.find("joker JOKER") != -1)//string::npos
        return "joker JOKER";

    int dash = line.find('-');

    //分开两手牌
    string car1 = line.substr(0, dash);
    string car2 = line.substr(dash + 1);

    //获取两手牌的张数
    int car1_cnt = count(car1.begin(), car1.end(), ' ') + 1;
    int car2_cnt = count(car2.begin(), car2.end(), ' ') + 1;

    //获取两手牌的各自第一张牌
    string car1_first = car1.substr(0, car1.find(' '));
    string car2_first = car2.substr(0, car2.find(' '));

    //两手牌的类型相同
    if (car1_cnt == car2_cnt) {
        string str = "345678910JQKA2jokerJOKER";

        if (str.find(car1_first) > str.find(car2_first))
            return car1;
        return car2;
    }
    
    //数量(类型)不相同
    //而且car1是炸弹
    if (car1_cnt == 4) 
        return car1;
    //数量(类型)不相同
    //而且car2是炸弹
    else if (car2_cnt == 4)
        return car2;

    //以上情况都不满足
    return "ERROR";
}
int main() {
    string line, res;
    while (getline(cin, line)) {
        res = FindMax(line);
        cout << res << endl;
    }
    return 0;

}

杨辉三角的变形

题目链接:

思路:

按照题目意思,可以发现第n行有2n - 1个元素,第i,j元素等于上一行第j - 2,j - 1,j三列元素之和,每一行的第一列和最后一列都为1,如果是第二列,则只是两个元素之和。

代码:

#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
    int n, m;
    while (cin >> n) {
        m = 2 * n - 1;
        vector<vector<int>> dp(n, vector<int>(m, 0));
        dp[0][0] = 1;
        for (int i = 1; i < n; i++) {
            //第一列和最后一列都为1
            dp[i][0] = dp[i][2 * i] = 1;
            for (int j = 1; j < 2 * i; ++j) {
                if (j == 1)
                //如果是第二列,则只是两个元素之和
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
                else
                //第i,j元素等于上一行第j - 2,j - 1,j三列元素之和
                    dp[i][j] = dp[i - 1][j - 2] + dp[i - 1][j - 1] + dp[i - 1][j];
            }
        }
        int k;
        for (k = 0; k < m; k++) {
            if (dp[n - 1][k] % 2 == 0 && dp[n - 1][k] != 0) {
                cout << k + 1 << endl;
                break;
            }
        }
        if (k == m)
            cout << -1 << endl;
    }
    return 0;
}

由于牛客更新了测试用例,加强了内存限制,因此上述用例在运行时会超出内存限制,所以上述使用生成杨辉三角,然后在第n行上寻找偶数的方式已经不合适,故进行更正。
通过以上的数据分析规律为 {-1,-1,2,3,2,4,2,3,2,4,...} ,即第n行上偶数所在的下标。
前两行没有偶数输出-1,包括第三行在内之后的行数,偶数出现的位置是有规律的,都是2、3、2、4...,这样循环往复。

代码:

#include<iostream>
#include<string>
using namespace std;
int main(int argc, char* argv[]) {
    int nRow = 0;
    while (cin >> nRow) {
        int res = -1;
        int myInt[] = {4, 2, 3, 2};
        if (nRow > 2)
            res = myInt[(nRow - 2) % 4];
        cout << res << endl;
    }
    return 0;
}

计算某字符出现次数

题目链接:

思路:

首先,字符串中包含有空格,因此我们使用 getline 函数获取一行数据,而不用cin ,因为 cin 函数会默认以空格截断输入作为输入的结束.
其次,因为在计算字符出现次数中,要求是不区分大小写的,因此在处理过程中,如果输入的是小写字母,则计数不但要加上小写字母的计数,还要加上大写字母的计数,反之大写字母也是同样如此,而在 ascii 表中,大写字母和小写字母的差值是 32 ( 'a’的ascii值是97 ; 'A’的ascii值是65 )
最后,把输入的字符按需转化为大写,然后遍历输入的字符串,并按需转化为大写,如果与输入的要被查找的字符串相同,则计数器++。

代码:

#include<iostream>
#include<string>
using namespace std;
int main() {
    string in_string = "";
    char find;
    int count = 0;
    getline(cin, in_string);
    cin >> find;
    //转化为大写
    if (find >= 97 && find <= 122) {
        find -= 32;
    }
    //遍历in_string
    for (auto& ch : in_string) {
    	//小写转大写
        if (ch >= 97 && ch <= 122) {
            ch -= 32;
        }
        if (ch == find) {
            count++;
        }
    }
    cout << count << endl;
    return 0;
}

end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有效的放假者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值