C++入门练习(4)

编程题#1:寻找下标

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

描述
已知一个整数数组x[],其中的元素彼此都不相同。找出给定的数组中是否有一个元素满足x[i]=i的关系,数组下标从0开始。
举例而言,如果x[]={-2,-1,7,3,0,8},则x[3] = 3,因此3就是答案。

输入
第一行包含一个整数n (0 < n < 100),表示数组中元素的个数。
第二行包含n个整数,依次表示数组中的元素。

输出
输出为一个整数,即满足x[i]=i的元素,若有多个元素满足,输出第一个满足的元素。若没有元素满足,则输出“N”。

样例输入:

第一组
6
-2 -1 7 3 4 8
第二组
6
9 9 9 9 9 9

样例输出:

第一组
3
第二组
N

参考答案:

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

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int a = 0;
		cin >> a;
		if (a == i) {
			cout << a << endl;
			return 0;
		}
	}
	cout << "N" << endl;
	return 0;
}

编程题#2:大整数的加减乘除

来源: POJ

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

描述
给出两个正整数以及四则运算操作符(+ - * /),求运算结果。
输入
第一行:正整数a,长度不超过100
第二行:四则运算符o,o是“+”,“-”,“*”,“/”中的某一个
第三行:正整数b,长度不超过100
保证输入不含多余的空格或其它字符

输出
一行:表达式“a o b”的值。

补充说明:
1.减法结果有可能为负数
2. 除法结果向下取整
3. 输出符合日常书写习惯,不能有多余的0、空格或其它字符

样例输入:

9876543210
+
9876543210

样例输出:

19753086420

参考答案:

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

string operator+(string a, string b)
{
    string res;
    int flag = 0;
    while(a.size() > b.size()) b = "0" + b;
    while(a.size() < b.size()) a = "0" + a;
    int len = a.size();
    for (int i = 0; i < len; i++)
    {
        int int_a = int(a[len-i-1]) - 48;
        int int_b = int(b[len-i-1]) - 48;
        int temp = (int_a + int_b + flag)%10;
        flag = int_a+int_b+flag >= 10 ? 1:0;
        res.push_back(temp+48);
    }
    if (flag) res += "1";
    while(res[res.size()-1] == '0') res.erase(res.end()-1,res.end());
    if(res.size() == 0) res.push_back('0');
    reverse(res.begin(), res.end());
    return res;
}

string operator-(string a, string b)
{
    string res;
    if (a == b)
    {
        res.push_back('0');
        return res;
    }
    int flag = 0, isNegetive = 0;
    while(a.size() > b.size()) b = "0" + b;
    while(a.size() < b.size()) a = "0" + a;
    int len = a.size();
    if(a < b)
    {
        string c = a;
        a = b;
        b = c;
        isNegetive = 1;
    }
    for (int i = 0; i < len; i++)
    {
        int int_a = int(a[len-i-1]) - 48;
        int int_b = int(b[len-i-1]) - 48;
        int temp;
        if(int_a - int_b - flag < 0)
        {
            temp = int_a - int_b - flag + 10;
            flag = 1;
        }
        else
        {
            temp = int_a - int_b - flag;
            flag = 0;
        }
        res.push_back(temp+48);
    }
    while(res[res.size()-1] == '0') res.erase(res.end()-1,res.end());
    if(res.size() == 0)
        res.push_back('0');
    if(isNegetive) res.push_back('-');
    reverse(res.begin(), res.end());
    return res;
}

string operator*(string a, string b)
{
    string res;
    for(unsigned int i = 0; i < b.size(); i++)
    {
        int mul = int(b[b.size()-i-1])-48;
        string sub_res;
        while(mul--) sub_res = operator+(sub_res, a);
        for (unsigned int j = 0; j < i; j++)
            sub_res.push_back('0');
        res = operator+(res, sub_res);
    }
    while(res[res.size()-1] == '0') res.erase(res.end()-1,res.end());
    if(res.size() == 0) res.push_back('0');
    return res;
}

bool isABiggerOrEqualThanB(string a, string b)
{
    while(a.size() > b.size()) b = "0" + b;
    while(a.size() < b.size()) a = "0" + a;
    if(a < b) return 0;
    else return 1;
}

string operator/(string a, string b)
{
    string res("0"), one("1");
    if(a.size() < b.size()) return res;
    if(a.size() == b.size() && a < b) return res;
    string subDividend("0"), dividor = b;
    while(a.size() > 0)
    {
        if(!isABiggerOrEqualThanB(subDividend, b))
        {
            if(subDividend[0] == '0') subDividend.clear();
            subDividend.push_back(a[0]);
            if(a.size() > 1) a = a.substr(1, a.size()-1);
            else a.clear();
        }
        string res_temp("0");
        while(isABiggerOrEqualThanB(subDividend, b))
        {
            subDividend = operator-(subDividend, b);
            res_temp = operator+(res_temp, one);
        }
        res.append(res_temp);
    }
    while(res[0] == '0') res = res.substr(1, res.size()-1);
    return res;
}

int main()
{
    string a, b, c;
    char op;
    cin >> a >> op >> b;
    switch(op)
    {
        case '+': c = operator+(a, b); break;
        case '-': c = operator-(a, b); break;
        case '*': c = operator*(a, b); break;
        case '/': c = operator/(a, b); break;
    }
    cout << c << endl;
}

编程题#3:四大湖

注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
我国有4大淡水湖。
A说:洞庭湖最大,洪泽湖最小,鄱阳湖第三。
B说:洪泽湖最大,洞庭湖最小,鄱阳湖第二,太湖第三。
C说:洪泽湖最小,洞庭湖第三。
D说:鄱阳湖最大,太湖最小,洪泽湖第二,洞庭湖第三。
已知这4个湖的大小均不相等,4个人每人仅答对一个,
请编程按照鄱阳湖、洞庭湖、太湖、洪泽湖的顺序给出他们的大小排名。
参考答案:(遍历)

#include <iostream>
using namespace std;

int A(int a, int b, int c, int d)//boyang, dongting, tai, hongze
{
    int cnt = 0;
    if(a==3) cnt++;
    if(b==1) cnt++;
    if(c==2) cnt++;
    if(d==4) cnt++;
    if(cnt==1) return 1;
    else return 0;
}

int B(int a, int b, int c, int d)//boyang, dongting, tai, hongze
{
    int cnt = 0;
    if(a==2) cnt++;
    if(b==4) cnt++;
    if(c==3) cnt++;
    if(d==1) cnt++;
    if(cnt==1) return 1;
    else return 0;
}

int C(int a, int b, int c, int d)//boyang, dongting, tai, hongze
{
    int cnt = 0;
    //if(a==3) cnt++;
    if(b==3) cnt++;
    //if(c==2) cnt++;
    if(d==4) cnt++;
    if(cnt==1) return 1;
    else return 0;
}

int D(int a, int b, int c, int d)//boyang, dongting, tai, hongze
{
    int cnt = 0;
    if(a==1) cnt++;
    if(b==3) cnt++;
    if(c==4) cnt++;
    if(d==2) cnt++;
    if(cnt==1) return 1;
    else return 0;
}

int main()
{
    int a,b,c,d;
    for(a=1;a<5;a++)
    {
        for(b=1;b<5;b++)
        {
            for(c=1;c<5;c++)
            {
                for(d=1;d<5;d++)
                {
                    if(A(a,b,c,d) && B(a,b,c,d) && C(a,b,c,d) && D(a,b,c,d))
                    {
                        cout << a << endl;
                        cout << b << endl;
                        cout << c << endl;
                        cout << d << endl;
                        return 0;
                    }
                }
            }
        }
    }
    return 0;
}

编程题#4:Tomorrow never knows?

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

描述
甲壳虫的《A day in the life》和《Tomorrow never knows》脍炙人口,如果告诉你a day in the life,真的会是tomorrow never knows?相信学了计概之后这个不会是难题,现在就来实现吧。
读入一个格式为yyyy-mm-dd的日期(即年-月-日),输出这个日期下一天的日期。可以假定输入的日期不早于1600-01-01,也不晚于2999-12-30。

输入
输入仅一行,格式为yyyy-mm-dd的日期。

输出
输出也仅一行,格式为yyyy-mm-dd的日期

样例输入:

2010-07-05

样例输出:

2010-07-06

提示
闰年的标准:
(1)普通年能被4整除且不能被100整除的为闰年。(如2004年就是闰年,1901年不是闰年)
(2)世纪年能被400整除的是闰年。(如2000年是闰年,1100年不是闰年)
可以利用一个字符变量吃掉输入的短横线(减号),输出时请活用setfill和setw 控制符。
参考答案:

#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
using namespace std;
int month_day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int isRunNian(int year);
void calNextDay(int & year, int & month, int & day);

int main()
{
    string s;
    cin >> s;
    string sTmp = s.substr(0, 4);
    int year = atoi(sTmp.c_str());
    sTmp = s.substr(5, 2);
    int month = atoi(sTmp.c_str());
    sTmp = s.substr(8, 2);
    int day = atoi(sTmp.c_str());
    //cout << year << month << day;
    if(isRunNian(year))
    {
        month_day[2] = 29;
    }
    else
    {
        month_day[2] = 28;
    }
    calNextDay(year, month, day);
    cout << year << '-' << setfill('0') << setw(2) << month << '-' << setfill('0') << setw(2) << day << endl;

}

int isRunNian(int year)
{
    if(year%100 == 0)//can not be divided by 100
    {
        if(year%400 == 0) return 1;
        else return 0;
    }
    else
    {
        if (year%4 == 0) return 1;
        else return 0;
    }
}

void calNextDay(int & year, int & month, int & day)
{
    if(day+1 > month_day[month])
    {
        month++;
        if(month > 12)
        {
            month = 1;
            year++;
        }
        day = 1;
    }
    else
    {
        day++;
    }
}

编程题#5:细菌实验分组

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

描述
有一种细菌分为A、B两个亚种,它们的外在特征几乎完全相同,仅仅在繁殖能力上有显著差别,A亚种繁殖能力非常强,B亚种的繁殖能力很弱。在一次为时一个 小时的细菌繁殖实验中,实验员由于疏忽把细菌培养皿搞乱了,请你编写一个程序,根据实验结果,把两个亚种的培养皿重新分成两组。

输入
输入有多行,第一行为整数n(n≤100),表示有n个培养皿。
其余n行,每行有三个整数,分别代表培养皿编号,试验前细菌数量,试验后细菌数量。

输出
输出有多行:
第一行输出A亚种培养皿的数量,其后每行输出A亚种培养皿的编号,按繁殖率升序排列。
然后一行输出B亚种培养皿的数量,其后每行输出B亚种培养皿的编号,也按繁殖率升序排列。

样例输入:

5
1 10 3456
2 10 5644
3 10 4566
4 20 234
5 20 232

样例输出:

3
1
3
2
2
5
4

提示
亚种内部细菌繁殖能力差异 远远小于 亚种之间细菌繁殖能力差异。
也就是说,亚种间任何两组细菌的繁殖率之差都比亚种内部两组细菌的繁殖率之差大。

参考答案:

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    int N;
    float num[100][4] = {0};
    int A[100] = {0}, B[100] = {0}, numA = 0, numB = 0;
    cin >> N;
    for (int i = 0; i < N; i++)
    {
        cin >> num[i][0] >> num[i][1] >> num[i][2];
        num[i][3] = num[i][2]/num[i][1]; //繁殖率计算
    }
	//排序
    int max_diff = 0, max_indx[2] = {0};
    for (int i = 0; i < N; i++)
    {
        for (int j = i+1; j < N; j++)
        {
            if(num[i][3] > num[j][3])
            {
                float tmp[4] = {num[i][0], num[i][1], num[i][2], num[i][3]};
                num[i][0] = num[j][0]; num[i][1] = num[j][1]; num[i][2] = num[j][2]; num[i][3] = num[j][3];
                num[j][0] = tmp[0];    num[j][1] = tmp[1];    num[j][2] = tmp[2];    num[j][3] = tmp[3];
            }
        }
    }
    //分组
    for (int i = 0; i < N; i++)
    {
        for (int j = i+1; j < N; j++)
        {

            int diff = abs(num[i][3]-num[j][3]);
            if (diff > max_diff)
            {
                max_diff = diff;
                if(num[i][3] > num[j][3]) {max_indx[0] = i; max_indx[1] = j;}
                else {max_indx[0] = j; max_indx[1] = i;}
            }
        }
    }
    for (int i = 0; i < N; i++)
    {
        if (abs(num[max_indx[0]][3] - num[i][3]) < abs(num[max_indx[1]][3] - num[i][3]))
        {
            A[numA] = num[i][0];
            numA++;
        }
        else
        {
            B[numB] = num[i][0];
            numB++;
        }

    }
    cout << numA << endl;
    for (int i = 0; i < numA; i++)
        cout << A[i] << endl;
    cout << numB << endl;
    for (int i = 0; i < numB; i++)
        cout << B[i] << endl;
}

编程题#6:流感传染

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

描述
有一批易感人群住在网格状的宿舍区内,宿舍区为n*n的矩阵,每个格点为一个房间,房间里可能住人,也可能空着。在第一天,有些房间里的人得了流感,以后每天,得流感的人会使其邻居传染上流感,(已经得病的不变),空房间不会传染。请输出第m天得流感的人数。

输入
第一行一个数字n,n不超过100,表示有n*n的宿舍房间。
接下来的n行,每行n个字符,’.’表示第一天该房间住着健康的人,’#’表示该房间空着,’@’表示第一天该房间住着得流感的人。
接下来的一行是一个整数m,m不超过100.

输出
输出第m天,得流感的人数

样例输入:

5
…#
.#.@.
.#@…
#…

4

样例输出:

16

参考答案:

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

int N, day, counter = 0;
int room[100][100] = {0}, temp[100][100];
void print()
{
    for(int i = 0; i < N; i++)
    {
       for(int j = 0; j < N; j++)
           cout << setw(4) << room[i][j] << " ";
       cout << endl;
    }
    cout << counter << endl;
}

void update()
{
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
            room[i][j] = temp[i][j];
}

int main()
{
    cin >> N;
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
        {
            char tmp;
            cin >> tmp;
            if (tmp == '.') room[i][j] = 1;//healthy
            else if(tmp == '@') {room[i][j] = -1; counter++;}//unhealthy
            else room[i][j] = 0;//no people
        }
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
            temp[i][j] = room[i][j];
    cin >> day;
    while(day-- >1)
    {
        for(int i = 0; i < N; i++)
            for(int j = 0; j < N; j++)
            {
                if(room[i][j] == -1)
                {
                    if(i>0 && temp[i-1][j] == 1) {temp[i-1][j] = -1; counter++;}
                    if(i<N-1 && temp[i+1][j] == 1) {temp[i+1][j] = -1; counter++;}
                    if(j>0 && temp[i][j-1] == 1) {temp[i][j-1] = -1; counter++;}
                    if(j<N-1 && temp[i][j+1] == 1) {temp[i][j+1] = -1; counter++;}
                }
            }
        update();
    }
    cout << counter;
}

编程题#7:发票统计

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

描述
有一个小型的报账系统,它有如下功能:
(1)统计每个人所报发票的总钱数
(2)统计每类发票的总钱数
将此系统简化为如下:假设发票类别共有A、B、C三种;一共有三个人,ID分别为1、2、3。

输入
系统输入包含三行,每行第一个数为人员ID(整型,1或2或3),第二个数为发票总张数(张数不超过100),之后是多个发票类别(字符型,A或B或C)和相应发票金额(单进度浮点型,不超过1000.0)。

输出
输出包含六行,前三行为每人(按ID由小到大输出)所报发票总钱数(保留两位小数),后三行为每类发票的总钱数(保留两位小数)。

样例输入:

1 5 A 1.0 A 2.0 C 1.0 B 1.0 C 1
3 3 B 1 C 2 C 1
2 4 B 1 A 1 C 1 A 1

样例输出:

1 6.00
2 4.00
3 4.00
A 5.00
B 3.00
C 6.00

参考答案:

#include <iostream>
#include "stdio.h"
using namespace std;

float moneyPerPerson[3] = {0};
float moneyPerClass[3] = {0};

int main()
{
    for (int i = 0; i < 3; i++)
    {
        int N;
        int id;
        cin >> id;
        cin >> N;
        for(int j = 0; j < N; j++)
        {
            char classes;
            cin >> classes;
            float money;
            cin >> money;
            moneyPerClass[classes-0x41] += money;
            moneyPerPerson[id-1] += money;
        }
    }
    for (int i = 0; i < 3; i++)
    {
        printf("%d %0.2f \n", i+1, moneyPerPerson[i]);
    }
    for (int i = 0; i < 3; i++)
    {
        printf("%c %0.2f \n", (char)(i+0x41), moneyPerClass[i]);
    }
}

更多题目

请见github:
https://github.com/chenyr0021/C_plus_plus-basic-exercises

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值