C++入门练习(2)

题目收集自Coursera《程序设计与算法》课程作业题。

目录

年龄与疾病

成绩判断

找出第k大的数

人民币支付

 约瑟夫问题

分数求和


年龄与疾病

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

某医院想统计一下某项疾病的获得与否与年龄是否有关,需要对以前的诊断记录进行整理。

输入

共2行,第一行为过往病人的数目n(0 < n <= 100),第二行为每个病人患病时的年龄。

输出

每个年龄段(分四段:18以下,19-35,36-60,大于60注意看样例输出的格式)的患病人数占总患病人数的比例,以百分比的形式输出,精确到小数点后两位(double)。关于c++的格式化的输入输出,请参考:http://www.cplusplus.com/reference/iomanip。也可以在网上搜索一下,资料很多的。

样例输入

10
1 11 21 31 41 51 61 71 81 91

样例输出

1-18: 20.00%
19-35: 20.00%
36-60: 20.00%
60-: 40.00%

提示

注意最后一行的输出是“60-: ”,而不是“61-: ”。

每个冒号之后有一个空格。

输出可以用 cout<<fixed<<setprecision(2) << f; 来保留f后面的两位小数。

参考答案

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

int main(){
	int n;
	cin >> n;
	double n1 = 0, n2 = 0, n3 = 0, n4 = 0;
	for (int i = 0; i < n; i++) {
		int age;
		cin >> age;
		if (age <= 18)
			n1++;
		else if (age <= 35)
			n2++;
		else if (age <= 60)
			n3++;
		else
			n4++;
	}
	n1 /= n;
	n2 /= n;
	n3 /= n;
	n4 /= n;
	cout << fixed << setprecision(2);
	cout << "1-18: " << n1 * 100 << '%' << endl;
	cout << "19-35: " << n2 * 100 << '%' << endl;
	cout << "36-60: " << n3 * 100 << '%' << endl;
	cout << "60-: " << n4 * 100 << '%' << endl;
	return 0;
}

成绩判断

注意: 总时间限制: 1000ms 内存限制: 6000kB

描述

输入一个0--100的分数,判断分数代表什么等级。

95<=分数<=100, 输出1

90<=分数<95,输出2

85<=分数<90,输出3

80<=分数<85,输出4

70<=分数<80,输出5

60<=分数<70输出6

分数 < 60;输出7.

输入

n

输出

m

参考答案

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

int main(){
	int sco;
	cin >> sco;
	if (sco == 100) cout << 1 << endl;
	else if (sco >= 80) cout << (4 - (sco - 80) / 5) << endl;
	else if (sco >= 60) cout << (6 - (sco - 60) / 10) << endl;
	else cout << 7 << endl;
	return 0;
}

找出第k大的数

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

用户输入N和K,然后接着输入N个正整数(无序的),程序在不对N个整数排序的情况下,找出第K大的数。注意,第K大的数意味着从大到小排在第K位的数。

输入

N

K

a1 a2 a3 a4 ..... aN

输出

b

参考答案

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

int main(){
	int N, K;
	cin >> N;
	cin >> K;
	int n[100] = { 0 };
	for (int i = 0; i < N; i++) {
		cin >> n[i];
	}
	while (K--) {
		int max = n[0], index = 0;
		for (int i = 1; i < N; i++) {
			if (max < n[i]) {
				max = n[i];//记录当前最大值及其下标
				index = i;
			}
		}
		if (K > 0)
			n[index] = 0;//将当前最大值去掉
		else cout << n[index] << endl;//最后一次循环时输出当前最大
	}

	return 0;

提示

这是一道很经典的算法问题,是公司面试的常见考题。以后学习递归之后再回头看看这道题,或许有新解法

人民币支付

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

从键盘输入一指定金额(以元为单位,如345),然后输出支付该金额的各种面额的人民币数量,显示100元,50元,20元,10元,5元,1元各多少张,要求尽量使用大面额的钞票

输入

一个小于1000的正整数。

输出

输出分行,每行显示一个整数,从上到下分别表示100元,50元,20元,10元,5元,1元人民币的张数

样例输入

735

样例输出
 

7
0
1
1
1
0

参考答案

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

int main(){
	int money;
	cin >> money;
	int a[6] = { 100, 50, 20, 10, 5, 1 };
	for (int i = 0; i < 6; i++) {
		cout << money / a[i] << endl;
		money %= a[i];
	}
	return 0;
}

 约瑟夫问题

总时间限制: 1000ms 内存限制: 65536kB

描述

约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入

每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:

0 0

输出

对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号

样例输入

6 2
12 4
8 3
0 0

样例输出

5
1
7

参考答案

#include<iostream>
using namespace std;

//一共最多有300只猴子
int succedent[300]; //这个数组用于保存一个猴子后一位是谁,
      //比如“next[5]的值是7”就是说5号猴子的下一位是7号猴子,6号猴子已经在之前退出了。
int precedent[300];//这个数组用于保存一个猴子前一位是谁,用法和上面的类似。

int main() {
  int n, m;
  while (true) {
    cin >> n >> m;
    if (n == 0 && m == 0)
      break;
    for (int i = 0; i < n - 1; i++) {
      succedent[i] = i + 1;
      precedent[i + 1] = i;
    }
    succedent[n - 1] = 0;
    precedent[0] = n - 1;

    int current = 0;
    while (true) {
      //如果一共要报m次号,那么取m-1次succedent之后就是需要退出的那只猴子
      for (int count = 0; count < m-1; count++)
        current = succedent[current];

      int pre = precedent[current];
      int suc = succedent[current];
      //让current号猴子退出很简单,就是把前一位的“下一位”指向current的下一位,
      //下一位的“前一位”指向current的前一位就好了
      succedent[pre] = suc;
      precedent[suc] = pre;
      if (pre == suc) {
        //如果只剩下两个了,那么每个人的前位和后位就是同一个了。
        //current是退出的,那么另一个就是剩下的。
        //我们的序号是从0编号的,输出时要加一
        cout << pre+1 << endl;
        break;
      }
      current = suc;
    }
  }
  return 0;
}

分数求和

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

输入n个分数并对他们求和,用约分之后的最简形式表示。

比如:

q/p = x1/y1 + x2/y2 +....+ xn/yn,

q/p要求是归约之后的形式。

如:5/6已经是最简形式,3/6需要规约为1/2, 3/1需要规约成3,10/3就是最简形式。

PS:分子和分母都没有为0的情况,也没有出现负数的情况

输入

第一行的输入n,代表一共有几个分数需要求和

接下来的n行是分数

输出

输出只有一行,即归约后的结果

样例输入

2
1/2
1/3

样例输出

5/6

参考答案

#include<iostream>
using namespace std;

int main() {
  int n;
  cin >> n;
  int sumn = 0, sumd = 1;//储存结果,sumn/sumd
  while (n--) {
    int num, deno;
    char slash;//专门用来吃掉/的
    cin >> num >> slash >> deno;
    //先相加 a/b + c/d = (a*d+c*b)/(b*d)
    sumn = sumn*deno + num*sumd;
    sumd = sumd*deno;
  }
  //后约分
  //先求最大公约数gcd,这里用的是欧几里得法
  int a = sumd, b = sumn, c;
  while (a != 0) {
    c = a; a = b%a; b = c;
  }
  int gcd = b;
  //分子分母同时除以gcd就可以完成约分
  sumd /= gcd;
  sumn /= gcd;
  if (sumd > 1)
    cout << sumn << '/' << sumd << endl;
  else
    cout << sumn << endl;
  return 0;
}
//我们计算过程中结果分母是不断乘以新输入的分母,最后约分的。这样可能导致这个过程中分母过大溢出。
//这道题的数据比较简单,并没有出现那种情况。但大家可以思考一下,如果出现了那种情况怎么办呢?(不要用大整数啊)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值