目录
因题集题目较多,另外两部分题集请移步这里:
7-1 求整数均值
本题要求编写程序,计算4个整数的和与平均值。题目保证输入与输出均在整型范围内。
输入格式:
输入在一行中给出4个整数,其间以空格分隔。
输出格式:
在一行中按照格式“Sum = 和; Average = 平均值”顺序输出和与平均值,其中平均值精确到小数点后一位。
输入样例:
1 2 3 4
输出样例:
Sum = 10; Average = 2.5
思路:简单模拟题,根据题干要求模拟即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a, b, c, d, res;
double ave;
cin >> a >> b >> c >> d;
res = a + b + c + d;
ave = res * 1.0 / 4;
printf("Sum = %d; Average = %.1lf", res, ave);
system("pause");
return 0;
}
7-2 判断回文字符串
克里斯托弗·诺兰 是一名电影导演,他非常擅长拍摄科幻类型的影片,最新的影片《信条》讲述的是一个时空转换的故事,影片中的一个特点是时空的一个对称性质。影片的英文名《TENET》也充分体现了对称的特点。
类似于“TENET"这样正读和反读都一样的字符串英文中被称为回文,实际上就是一个左右对称的字符串。本题要求设计一个程序,判断一个输入的字符串是否为回文,并输出其长度。
在这里,我们区分大小写,例如 "Tenet" 就不认为是一个回文,因为 'T' != 't'
。
输入格式:
一行中输入一个以换行结尾的字符串(不包含空格,长度不超过40)。
输出格式:
如果是回文,则输出YES, n
,这里n
是回文字符串的长度;如果不是回文,输出NO, n
。例如,如果输入 TENET,那么输出就是 YES, 5
。
输入样例1:
TENET
输出样例1:
YES, 5
输入样例2:
Tenet
输出样例2:
NO, 5
思路:用string类型的变量存储字符串,利用两个指针i以及j分别指向字符串的头和尾,若i和j指向的字符相同,则均向中间靠拢,直到i>=j时循环退出,若字符不相同则跳出,最终利用判断语句进行判断输出即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, n;
string s;
cin >> s;
i = s[0], j = s[s.length() - 1];
while (i < j) {
if (s[i] != s[j]) break;
i++;
j--;
}
if (i >= j)
cout << "YES, " << s.length();
else
cout << "NO, " << s.length();
system("pause");
return 0;
}
7-3 跟奥巴马一起画方块
美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!
输入格式:
输入在一行中给出正方形边长N(3≤N≤21)和组成正方形边的某种字符C
,间隔一个空格。
输出格式:
输出由给定字符C
画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整)。
输入样例:
10 a
输出样例:
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
思路:因为题干要求输出的行数是列数的50%(四舍五入取整),通过观察不难发现,当列数为奇数的时候均为向上取整,所以我们用一个ceil函数即可成功包括n为奇数以及偶数的情况
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n;
char op;
scanf("%d %c", &n, &op);
for (i = 0; i < (int)ceil(n * 1.0 / 2); i++) {
for (j = 0; j < n; j++) {
cout << op;
}
cout << endl;
}
system("pause");
return 0;
}
7-4 杨辉三角
打印n行杨辉三角,n<10
输入格式:
直接输入一个小于10的正整数n。
输出格式:
输出n行杨辉三角,每个数据输出占4列。
输入样例:
5
输出样例:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
思路:根据杨辉三角的特性,每行的首尾均为1,利用二维数组模拟即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n;
cin >> n;
vector<vector<int>>dp(n, vector<int>(n, 0));
dp[0][0] = 1;
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
if (j == 0 || i == j)
dp[i][j] = 1;
else
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
}
}
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
printf("%4d", dp[i][j]);
}
cout << endl;
}
system("pause");
return 0;
}
7-5 输出三角形面积和周长
本题要求编写程序,根据输入的三角形的三条边a、b、c,计算并输出面积和周长。注意:在一个三角形中, 任意两边之和大于第三边。三角形面积计算公式:area=√ ̄(s(s−a)(s−b)(s−c)),其中s=(a+b+c)/2。
输入格式:
输入为3个正整数,分别代表三角形的3条边a、b、c。
输出格式:
如果输入的边能构成一个三角形,则在一行内,按照
area = 面积; perimeter = 周长
的格式输出,保留两位小数。否则,输出
These sides do not correspond to a valid triangle
输入样例1:
5 5 3
输出样例1:
area = 7.15; perimeter = 13.00
输入样例2:
1 4 1
输出样例2:
These sides do not correspond to a valid triangle
思路:根据题干公式模拟即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n, a, b, c;
double area, s;
cin >> a >> b >> c;
if (a + b > c && a + c > b && b + c > a) {
s = (a + b + c) * 1.0 / 2;
area = sqrt(s * (s - a) * (s - b) * (s - c));
printf("area = %.2lf; perimeter = %.2lf", area, (double)a + b + c);
} else {
cout << "These sides do not correspond to a valid triangle" << endl;
}
system("pause");
return 0;
}
7-6 输出三角形字符阵列
本题要求编写程序,输出n行由大写字母A开始构成的三角形字符阵列。
输入格式:
输入在一行中给出一个正整数n(1≤n<7)。
输出格式:
输出n行由大写字母A开始构成的三角形字符阵列。格式见输出样例,其中每个字母后面都有一个空格。
输入样例:
4
输出样例:
A B C D
E F G
H I
J
思路:根据题干要求模拟即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n;
char op = 'A';
cin >> n;
for (i = n; i > 0; i--) {
for (j = i; j > 0; j--) {
cout << op << " ";
op++;
}
cout << endl;
}
system("pause");
return 0;
}
7-7 计算火车运行时间
本题要求根据火车的出发时间和达到时间,编写程序计算整个旅途所用的时间。
输入格式:
输入在一行中给出2个4位正整数,其间以空格分隔,分别表示火车的出发时间和到达时间。每个时间的格式为2位小时数(00-23)和2位分钟数(00-59),假设出发和到达在同一天内。
输出格式:
在一行输出该旅途所用的时间,格式为“hh:mm”,其中hh为2位小时数、mm为2位分钟数。
输入样例:
1201 1530
输出样例:
03:29
思路:因为出发和到达均在同一天,所以可以先将小时转换为分钟进行运算,最后再转化为小时制输出即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n, time1, time2;
int mm1, mm2, hh, mm;
cin >> time1 >> time2;
mm1 = time1 / 100 * 60 + time1 % 100;
mm2 = time2 / 100 * 60 + time2 % 100;
mm = mm2 - mm1;
hh = mm / 60;
mm = mm - hh * 60;
printf("%02d:%02d", hh, mm);
system("pause");
return 0;
}
7-8 字符串替换
本题要求编写程序,将给定字符串中的大写英文字母按以下对应规则替换:
原字母 | 对应字母 |
---|---|
A | Z |
B | Y |
C | X |
D | W |
… | … |
X | C |
Y | B |
Z | A |
输入格式:
输入在一行中给出一个不超过80个字符、并以回车结束的字符串。
输出格式:
输出在一行中给出替换完成后的字符串。
输入样例:
Only the 11 CAPItaL LeTtERS are replaced.
输出样例:
Lnly the 11 XZKRtaO OeGtVIH are replaced.
思路:可以利用字符数组优先存储其对应字母,然后遍历进行一一替换,这里我采用map哈希表,因为哈希表具有查找效率高特点且不费空间,最后进行遍历进行替换
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n;
char op1 = 'A', op2 = 'Z';
char * ch = new char[100];
cin.getline(ch, 100, '\n');
string s;
map<char, char>mp;
for (i = 0; i < 26; i++) {
mp[op1] = op2;
op1++;
op2--;
}
s = ch;
for (i = 0; i < s.length(); i++) {
if (mp.find(s[i]) != mp.end()) {
s[i] = mp[s[i]];
}
}
cout << s << endl;
system("pause");
return 0;
}
7-9 猴子吃桃问题
一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个;第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第N天早上想再吃时,见只剩下一个桃子了。问:第一天共摘了多少个桃子?
输入格式:
输入在一行中给出正整数N(1<N≤10)。
输出格式:
在一行中输出第一天共摘了多少个桃子。
输入样例:
3
输出样例:
10
思路:因为所需解决的数据比较小,所以递归可能比较好理解,可以根据题干进行递归模拟,具体可以参照代码
AC代码:
#include<bits/stdc++.h>
using namespace std;
int solve(int n, int count) {
if (n == 1)
return count;
else {
return solve(n - 1, (count + 1) * 2);
}
}
int main()
{
int i, j, k, n;
cin >> n;
int res = solve(n, 1);
cout << res << endl;
system("pause");
return 0;
}
7-10 逆序的三位数
程序每次读入一个正3位数,然后输出按位逆序的数字。注意:当输入的数字含有结尾的0时,输出不应带有前导的0。比如输入700,输出应该是7。
输入格式:
每个测试是一个3位的正整数。
输出格式:
输出按位逆序的数。
输入样例:
123
输出样例:
321
思路:利用while循环,每次循环均让n / 10,依次用结果变量存储输入数据的最后一位即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n, res = 0;
cin >> n;
while (n) {
res = res * 10 + n % 10;
n /= 10;
}
cout << res << endl;
system("pause");
return 0;
}
7-11 兔子繁衍问题
一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?
输入格式:
输入在一行中给出一个不超过10000的正整数N。
输出格式:
在一行中输出兔子总数达到N最少需要的月数。
输入样例:
30
输出样例:
9
思路:不难看出此题为一道变相的斐波那契数列,利用递归或迭代以及动态规划均可以解决
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n, res = 0;
cin >> n;
vector<int>nums(2, 1);
if (n == 0 || n == 1)
cout << 1 << endl;
else {
while (nums[nums.size() - 1] < n) {
res = nums[nums.size() - 1] + nums[nums.size() - 2];
nums.push_back(res);
}
cout << nums.size();
}
system("pause");
return 0;
}
7-12 三天打鱼两天晒网
中国有句俗语叫“三天打鱼两天晒网”。假设某人从某天起,开始“三天打鱼两天晒网”,问这个人在以后的第N天中是“打鱼”还是“晒网”?
输入格式:
输入在一行中给出一个不超过1000的正整数N。
输出格式:
在一行中输出此人在第N天中是“Fishing”(即“打鱼”)还是“Drying”(即“晒网”),并且输出“in day N”。
输入样例1:
103
输出样例1:
Fishing in day 103
输入样例2:
34
输出样例2:
Drying in day 34
思路:先对n进行取余,然后对其进行分情况讨论即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n, num;
cin >> n;
num = n;
n = n % 5;
if (n >= 1 && n <= 3)
cout << "Fishing in day " << num << endl;
else
cout << "Drying in day " << num << endl;
system("pause");
return 0;
}
7-13 进制转换
将十进制整数n(−231≤n≤231−1)转换成k(2≤k≤16)进制数。注意,10~15分别用字母A、B、C、D、E、F表示。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据输入两个整数n和k。
输出格式:
对于每组测试,先输出n,然后输出一个空格,最后输出对应的k进制数。
输入样例:
4
5 3
123 16
0 5
-12 2
输出样例:
5 12
123 7B
0 0
-12 -1100
思路:根据进制转换的定义,将十进制数不断除以所需转化的进制数,依次保存每次除后的余数(这里可以利用字符串进行保存)即可(同样我们可以利用map哈希表优先进行存储10进制以后的数位,方便后期替换),这里先得到的余数为最低位,后得到的为最高位,最后将字符串进行翻转为最终转换后的进制
AC代码:
#include<bits/stdc++.h>
using namespace std;
map<int, string>mp = {{10, "A"}, {11, "B"}, {12, "C"}, {13, "D"}, {14, "E"}, {15, "F"}};
pair<int, string> solve () {
int i, j, k, n, num, flag = 1;
string s = "";
cin >> n >> k;
num = n;
if (n == 0)
return pair<int, string>(0, "0");
if (n < 0) {
flag = -1;
n = -n;
}
while (n) {
if (n % k >= 10)
s += mp[n % k];
else
s += to_string(n % k);
n /= k;
}
if (flag == -1)
s += "-";
reverse(s.begin(), s.end());
return pair<int, string>(num, s);
}
int main()
{
int i, j, k, n, t;
cin >> t;
vector<pair<int, string>>res;
while (t--) {
res.push_back(solve());
}
for (i = 0; i < res.size(); i++) {
cout << res[i].first << " " << res[i].second << endl;
}
system("pause");
return 0;
}
7-14 出生年
以上是新浪微博中一奇葩贴:“我出生于1988年,直到25岁才遇到4个数字都不相同的年份。”也就是说,直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求,自动填充“我出生于y
年,直到x
岁才遇到n
个数字都不相同的年份”这句话。
输入格式:
输入在一行中给出出生年份y
和目标年份中不同数字的个数n
,其中y
在[1, 3000]之间,n
可以是2、或3、或4。注意不足4位的年份要在前面补零,例如公元1年被认为是0001年,有2个不同的数字0和1。
输出格式:
根据输入,输出x
和能达到要求的年份。数字间以1个空格分隔,行首尾不得有多余空格。年份要按4位输出。注意:所谓“n
个数字都不相同”是指不同的数字正好是n
个。如“2013”被视为满足“4位数字都不同”的条件,但不被视为满足2位或3位数字不同的条件。
输入样例1:
1988 4
输出样例1:
25 2013
输入样例2:
1 2
输出样例2:
0 0001
思路:因为set容器不会存储重复元素,所以我们可以利用set容器进行存储每一个年份,然后对count进行判断即可,因为当年份小于1000的时候一定会在高位补零,所以我们可以优先存储0,然后在对年份进行存储判断,每次循环记得都要清空set容器
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n, count, num;
cin >> n >> count;
num = n;
set<int>st;
int n_temp = n;
if (n_temp < 1000)
st.insert(0);
while (n_temp) {
st.insert(n_temp % 10);
n_temp /= 10;
}
while (st.size() != count) {
st.clear();
n++;
int temp = n;
if (temp < 1000)
st.insert(0);
while (temp) {
st.insert(temp % 10);
temp /= 10;
}
}
printf("%d %04d", n - num, n);
system("pause");
return 0;
}
7-15 输出所有大于平均值的数
本题要求编写程序,将输入的n个整数存入数组a中,然后计算这些数的平均值,再输出所有大于平均值的数。
输入格式:
输入在第1行中给出一个正整数n(1≤n≤10),第2行输入n个整数,其间以空格分隔。题目保证数据不超过长整型整数的范围。
输出格式:
输出在第1行给出平均值,保留2位小数。在第2行输出所有大于平均值的数,每个数的后面有一个空格;如果没有满足条件的数,则输出空行。
如果输入的n不在有效范围内,则在一行中输出"Invalid."。
输入样例1:
10
55 23 8 11 22 89 0 -1 78 186
输出样例1:
47.10
55 89 78 186
输入样例2:
0
输出样例2:
Invalid.
思路:根据题面意思进行模拟即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, k, n;
cin >> n;
if (n < 1 || n > 10)
cout << "Invalid." << endl;
else {
vector<int>nums(n, 0);
double ave = 0;
bool flag = false;
for (i = 0; i < n; i++) {
cin >> nums[i];
ave += nums[i];
}
ave = ave * 1.0 / n;
printf("%.2lf\n", ave);
for (i = 0; i < n; i++) {
if (nums[i] > ave) {
flag = true;
cout << nums[i] << " ";
}
}
if (!flag)
cout << endl;
}
system("pause");
return 0;
}
7-16 大整数A+B
输入两个整数A、B,求 A + B。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入2个正整数A、B。整数可能很大,但每个整数的位数不会超过1000。
输出格式:
对于每组测试输出两行数据;第一行输出"Case #:",#表示测试组号,第二行输出形式为“A + B = Sum”,Sum表示A+B的结果。每两组测试数据之间空一行。
输入样例:
2
1 2
88888888888888888888888 11111111111111111111111
输出样例:
Case 1:
1 + 2 = 3Case 2:
88888888888888888888888 + 11111111111111111111111 = 99999999999999999999999
思路:因为数据范围最大为1000个位数,所以我们可以用字符串进行存储,根据加法的特性,前一位要加上后一位所溢出的部分,所以我们可以利用一个变量将所算的那一位溢出的部分进行存储,然后再加到前一位上,依次进行即可,若加到最高的一位依旧有溢出,则将溢出插入到结果字符串的首位即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
vector<string> solve(vector<pair<string, string>>& nums) {
int i, j, k, n;
vector<string>res;
for (i = 0; i < nums.size(); i++) {
int right1, right2, item = 0;
string s1, s2, s = "";
s1 = nums[i].first;
s2 = nums[i].second;
right1 = s1.length() - 1;
right2 = s2.length() - 1;
while (right1 >= 0 || right2 >= 0) {
int temp;
if (right1 < 0)
temp = (int)(s2[right2] - '0') + item;
else if (right2 < 0)
temp = (int)(s1[right1] - '0') + item;
else
temp = (int)(s1[right1] - '0') + (int)(s2[right2] - '0') + item;
s = to_string(temp % 10) + s;
item = temp / 10;
right1--;
right2--;
}
if (item > 0)
s = to_string(item) + s;
res.push_back(s);
}
return res;
}
int main()
{
int i, j, k, n, t;
cin >> t;
vector<pair<string, string>>nums(t);
vector<string>res;
for (i = 0; i < t; i++) {
cin >> nums[i].first >> nums[i].second;
}
res = solve(nums);
for (i = 0; i < res.size(); i++) {
if (i == 0) {
cout << "Case " << i + 1 << ":" << endl;
cout << nums[i].first << " + " << nums[i].second << " = " << res[i] << endl;
} else {
cout << endl;
cout << "Case " << i + 1 << ":" << endl;
cout << nums[i].first << " + " << nums[i].second << " = " << res[i] << endl;
}
}
system("pause");
return 0;
}
7-17 谁先倒
划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就输了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。
下面给出甲、乙两人的酒量(最多能喝多少杯不倒)和划拳记录,请你判断两个人谁先倒。
输入格式:
输入第一行先后给出甲、乙两人的酒量(不超过100的非负整数),以空格分隔。下一行给出一个正整数N
(≤100),随后N
行,每行给出一轮划拳的记录,格式为:
甲喊 甲划 乙喊 乙划
其中喊
是喊出的数字,划
是划出的数字,均为不超过100的正整数(两只手一起划)。
输出格式:
在第一行中输出先倒下的那个人:A
代表甲,B
代表乙。第二行中输出没倒的那个人喝了多少杯。题目保证有一个人倒下。注意程序处理到有人倒下就终止,后面的数据不必处理。
输入样例:
1 1
6
8 10 9 12
5 10 5 10
3 8 5 12
12 18 1 13
4 16 12 15
15 1 1 16
输出样例:
A
1
思路:存储二位的酒量,对每次循环进行判断,最终将结果输出即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i, j, n, volume1, volume2, num1, num2;
cin >> volume1 >> volume2;
cin >> n;
num1 = volume1;
num2 = volume2;
vector<vector<int>>nums(n, vector<int>(4, 0));
for (i = 0; i < n; i++) {
for (j = 0; j < 4; j++) {
cin >> nums[i][j];
}
}
i = 0;
while (i < n && volume1 >= 0 && volume2 >= 0) {
if (nums[i][0] + nums[i][2] == nums[i][3] && nums[i][0] + nums[i][2] != nums[i][1])
volume2--;
else if (nums[i][0] + nums[i][2] == nums[i][1] && nums[i][0] + nums[i][2] != nums[i][3])
volume1--;
i++;
}
if (volume1 < 0) {
cout << 'A' << endl;
cout << num2 - volume2 << endl;
} else {
cout << 'B' << endl;
cout << num1 - volume1 << endl;
}
system("pause");
return 0;
}
7-18 到底有多二
一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数,则程度增加0.5倍;如果还是个偶数,则再增加1倍。例如数字-13142223336
是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11×1.5×2×100%,约为81.82%。本题就请你计算一个给定整数到底有多二。
输入格式:
输入第一行给出一个不超过50位的整数N
。
输出格式:
在一行中输出N
犯二的程度,保留小数点后两位。
输入样例:
-13142223336
输出样例:
81.82%
思路:可以定义两个flag分别代表题干所说的那两个倍数,然后进行判断看倍数是否需要改变,最后将其带入相乘即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i = 0, j, k, n, len, count = 0;
double flag1 = 1, flag2 = 1, res = 0;
string s;
cin >> s;
len = s.length();
if (s[0] == '-') {
len--;
flag1 = 1.5;
i = 1;
}
if ((int)(s[s.length() - 1] - '0') % 2 == 0)
flag2 = 2;
for (i; i < s.length(); i++) {
if (s[i] == '2')
count++;
}
res = count * 1.0 / len * flag1 * flag2 * 100;
printf("%.2lf%%", res);
system("pause");
return 0;
}