完美数,扑克牌大小

问答题

问答题1:假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?

#include <stdio.h>
int main(){
	long long a = 1, b = 2, c = 3;
	printf("%d %d %d\n", a, b, c);
	return 0;
}

提示:变量 a,b,c的类型都是long long,占 8个字节 ,而 printf 取出来使用4个字节的,所以会出现偏差,另外printf()是一个库函数,C/C++函数的参数是从右往左入栈的;栈的生长方向是从高往低的;小端模式是低位存储在低字节

在这里插入图片描述

问答题2:如何捕获异常可以使得代码通过编译?

class A {
  public:
        A(){}
};
void foo(){
    throw new A;
}

(A)catch (A && x)

(B)catch (A * x)

(C)catch (A & x)

(D)以上都是

提示:throw new A; throw出的是A * 类型的指针所以 catch(A * x);

问答题3:下列代码应该如何修改?

template <class T>
struct sum {
	static void foo(T op1, T op2) {
		cout << op1 << op2;
	}
};
sum::foo(1, 3);

提示:函数模板可以不说明对象,类模板必须要说明类型,所以在类名的后面加<int>,意思就是加上 <int>才算是一个类,否则上面定义的那个 sum 只是一个模板.

问答题4:下列程序输出啥?

class A {
public:
	~A() {
		cout << "~A()";
	}
};
class B{
public:
	virtual ~B() {
		cout << "~B()";
	}
};
class C: public A, public B {
public:
	~C() {
		cout << "~C()";
	}
};
int main() {
	C * c = new C;
	B * b1 = dynamic_cast<B *>(c);
	A * a2 = dynamic_cast<A *>(b1);
	delete a2;
}

(A) ~C() ~B() ~A()
(B) ~C() ~A() ~B()
(C) A,B 都有可能
(D) 以上都不对

提示:dynamic_cast 动态转换从派生类转基类的时候可以,但是从基类转派生类可能会出错.因为要进行类型检测

dynamic_cast的转换格式:dynamic_cast (expression)

如果 expressiontype-id的基类,使用dynamic_cast进行转换时,在运行时就会检查expression是否真正的指向一个type-id类型的对象,如果是,则能进行正确的转换,获得对应的值;否则返回NULL,如果是引用,则在运行时就会抛出异常;

编程题

编程题1:完全数

完美数是一些特殊的自然数,它所有的真因子恰好等于它本身

真因子是除本身之外所有的约数,例 28

真因子为1,2,4,7,14 有 1 + 2 + 4 + 7 + 14 = 28

给定函数 count(int n) 用于计算 n 以内完全数的个数,返回n以内完全数的个数,异常情况返回-1

#include <iostream>
using namespace std;

int perfect(int m){
	int sum = 0;
	for (int i = 1; i < (m/2)+1; ++i) {
		if (m%i == 0) {
			sum += i;
		}
	}
	if (sum == m) {
		return 1;
	}
	else {
		return 0;
	}
}

void count(int n){
	int num = 0;
	for (int i = 3; i < n + 1; ++i) {
		if (perfect(i) == 1) {
			++num;
		}
	}
	if (num != 0) {
		cout << num<<endl;
	}else {
		cout << -1<<endl;
	}
}

int main(){
	int N = 0;
	while (cin >> N) {
		count(N);
	}
	return 0;
}

代码优化

优化部分,在寻找约数的时候,只要遍历到平方根的时候,就可以了;例 36 的约数,只要遍历到 6 就可以把所有的约数加起来.

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

int count(int num){
    int cnt = 0;
    if(num > 500000 || num <=0){
        return -1;
    }
    for(int i=2;i<num+1;++i){
        int sum = 0;
        for(int j=2;j<sqrt(i);++j){
            if(i%j == 0){
                // 平方数
                if(i/j==j){
                    sum+=j;
                }else{
                    sum+= j+i/j;
                }
            }
        }
        if(sum+1==i){
            cnt++;
        }
    }
    return cnt;
}
int main(){
    int n;
    while(cin>>n){
        cout<<count(n)<<endl;
    }
    return 0;
}

编程题2:扑克牌大小

一副扑克牌由54张组成,含 3~A 有四张、2 有 4 张,小王1张,大王1张

牌面从小到大用如下字符和字符串表示(小写joker表示小王,大写JOKER 表示大王)

请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR

基本规则如下:
(1) 输入每手牌可能是单牌、对子牌、顺子牌(连续5张)、三个牌、炸弹(四张相同)牌,王炸牌 这六种情况

(2) 除了炸弹和王炸可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系

(3)大小规则跟大家平时了解的常见规则相同,按大小比较,炸弹可以炸单牌,对子牌,顺子牌,三个牌,另外炸弹之间也比较牌面大小,对王是最大的牌;

(4) 输入的两手牌不会出现相等的情况

输入描述:输入两手牌,两手牌之间用"-"连接,每手牌的每张牌以空格分隔,"-"两边没有空格,如 4 4 4 4-joker JOKER

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

例:
输入:4 4 4 4-joker JOKER
输出:joker JOKER

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
	string line;
	while (getline(cin, line)) {
		// 王炸最大,直接输出
		if (line.find("joker JOKER") != -1)
			cout << "joker JOKER" << endl;
		else {
			int dash = line.find('-');
			// 分开两手牌
			string car1 = line.substr(0, dash);
			string car2 = line.substr(dash + 1);
			// 获取空格的次数,牌数为 c + 1
			int c1 = count(car1.begin(), car1.end(), ' ');
			int c2 = count(car2.begin(), car2.end(), ' ');
			// 拿到第一张牌
			string first1 = car1.substr(0, car1.find(' '));
			string first2 = car2.substr(0, car2.find(' '));
			string str = "345678910JQKA2jokerJOKER";
			if (c1 == c2) {
				// 只要牌数相等,则第一张牌大的即为大
				if (str.find(first1) > str.find(first2))
					cout << car1 << endl;
				else
					cout << car2 << endl;
			}
			else{
				// 牌数不相同,说明类型不同 , 只有炸弹可以和其它牌比较
				// 其它类型都是错误的
				if (c1 == 3)
					cout << car1 << endl;
				else if (c2 == 3)
					cout << car2 << endl;
				else
					cout << "ERROR" << endl;
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序猿的温柔香

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

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

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

打赏作者

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

抵扣说明:

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

余额充值