[每日习题] 完全数计算 扑克牌大小 ——牛客习题

        hello,大家好,这里是bang___bang_,今天也还是记录2道牛客习题,1道简单题(完全数计算);1道中等题(扑克牌大小)。

目录

1️⃣完全数计算

2️⃣扑克牌大小


1️⃣完全数计算

完全数计算_牛客题霸_牛客网 (nowcoder.com)

描述:

        完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。

        它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身

例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

        输入n,请输出n以内(含n)完全数的个数。

数据范围: 1≤n≤5×10^5 

输入描述:

输入一个数字n

输出描述:

输出不超过n的完全数的个数

示例:

输入:1000

输出:3

解题思路: 该数的约数和等于数本身。

        约数相加求和与本身比较,相等计数+1。

实现代码:

#include <iostream>
#include<cmath>
using namespace std;

bool get_div_num(int n)
{
    int sum=1;
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            sum+=i;
            //去掉重复的约数
            if(n/i!=i)
            {
                sum+=n/i;
            }
        }
    }
    return sum==n;
}
int main() {
    int n=0;
    while(cin>>n)
    {
        int count=0;
        for(int i=2;i<=n;i++)
        {
            if(get_div_num(i))
            {
                count++;
            }
        }
        cout<<count<<endl;
    }
    return 0;
}

2️⃣扑克牌大小

扑克牌大小_牛客题霸_牛客网 (nowcoder.com) 

描述:

        扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A,2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):)
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
        输入两手牌,两手牌之间用“-”连接,每手牌的每张牌以空格分隔,“-”两边没有空格,如:4 4 4 4-joker JOKER
        请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR

基本规则:
(1)输入每手牌可能是个子,对子,顺子(连续5张),三个,炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子)
(3)大小规则跟大家平时了解的常见规则相同,个子,对子,三个比较牌面大小;顺子比较最小牌大小炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌
(4)输入的两手牌不会出现相等的情况。

答案提示:
(1)除了炸弹和对王之外,其他必须同类型比较。
(2)输入已经保证合法性,不用检查输入是否是合法的牌。

(3)输入的顺子已经经过从小到大排序,因此不用再排序了.

数据范围:保证输入合法

输入描述:

        输入两手牌,两手牌之间用“-”连接,每手牌的每张牌以空格分隔,“-”两边没有空格,如4 4 4 4-joker JOKER。

输出描述:

        输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。

示例: 

输入:4 4 4 4-joker JOKER

输出:joker JOKER

substr截取字符串函数:从pos位置开始截取截取长度为len的子串。string函数参数中npos表示”直到字符串结束“。

basic_string substr (size_type pos = 0, size_type len = npos) const;

解题思路:

        1.判断有无鬼牌,有则返回鬼牌。

        2.将字符串分割为两手牌。

        3.获取两手牌的第一张牌。(为了接下来比较大小)

        4.判断两手牌数量,相同则表示两手牌是一种类型,进入斗地主规则,返回牌面大的。

        5.合法前提下,手牌数不同,只能是有一副手牌是鬼牌或者炸弹,鬼牌已在步骤1解决,只剩下炸弹, 判断哪副手牌的数量是4,就返回那副手牌(即炸弹)。

        6.其余剩下的均不符合比较关系,返回ERROR。

实现代码:

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

string CmpCard(const string &line)
{
    //判断是否有鬼牌
    if(line.find("joker JOKER")!=string::npos)
    {
        return "joker JOKER";
    }
    //分割手牌
    int pos=line.find('-');
    string card1=line.substr(0,pos);
    string card2=line.substr(pos+1);
    //统计手牌数(空格划分,统计空格数再+1)
    int cnt1=count(card1.begin(),card1.end(),' ')+1;
    int cnt2=count(card2.begin(),card2.end(),' ')+1;
    //获取第一张牌
    string card1_first=card1.substr(0,card1.find(' '));
    string card2_first=card2.substr(0,card2.find(' '));
    //牌数相同,常规比较,斗地主规则    
    if(cnt1==cnt2)
    {
        //比较串,直接比较在标准串的下标大小
        string str="3 4 5 6 7 8 9 10 J Q K A 2";
        if(str.find(card1_first)>str.find(card2_first))
            return card1;
        return card2;
    }
    //如果牌数不同,鬼牌情况已排除,不合法的牌不会输入,只剩单副手牌炸弹情况
    if(cnt1==4)
        return card1;
    if(cnt2==4)
        return card2;
    //剩余情况均不存在比较关系
    return "ERROR";

}


int main() {
    string line,res;
    while(getline(cin,line))
    {
        res=CmpCard(line);
        cout<<res<<endl;
    }
}

文末结语,本文记录2道牛客习题(完全数计算,扑克牌大小),旨在记录,如有需要,希望能有所帮助!

猜你喜欢

转载自blog.csdn.net/bang___bang_/article/details/132010091