34005 - 汽水瓶
时间限制 : 1 秒
内存限制 : 128 MB
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
输入
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。
输出
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
样例
输入
3 10 81 0
输出
1 5 40
答案:
#include<iostream>
using namespace std;
int main() {
int N;
while (true) {
cin >> N;
if (!N) {
break;
}
else {
int r = N % 3;//不能兑换的瓶子
int exchange = N / 3;//可兑换的瓶子
int sum = r + exchange;//喝完后的瓶子加上之前不能兑换的瓶子
int count = exchange;//喝水的总数
while (sum >= 2) {
if (sum == 2) {
count++;
break;
}
else {
r = sum % 3;
exchange = sum / 3;
count += exchange;
sum = r + exchange;
}
}
cout << count << endl;
}
}
return 0;
}
分析:这道题首先我们要格外注意只剩下两个瓶子的情况,原则上是不能继续兑换水的,但是题目特意交代可以通过接一瓶水喝完后凑齐一瓶水再还给老板,这个题目比之前单纯的兑换喝水问题加了一点难度,因此要特别留意一下空瓶子为2的时候。
是否通过:
34006 - 数字竞技
时间限制 : 1 秒
内存限制 : 128 MB
小灰灰和小东东在玩一种竞技游戏。在游戏中,小灰灰给小东东由n个正整数组成的序列以及m条操作指令,需要小东东按照指令来对n个整数进行操作。其中每条指令都包括二个整数(a, b),意义如下:
如果a大于0,表示将序列中第b个数乘于2;
如果a小于0,表示将序列中第b个数加上2;
如果a等于0,则忽略此条指令。
游戏结束后,小东东需要求出序列中的最大值。现在小东东求助于你,希望你能用计算机编程求出他需要的答案。题目保证计算结果在int的表示范围内。
输入
输入数据第一行为一整数T,表示有T组数据。每组输入数据第一行有二个整数n, m, (1 <= n <= 100), (1 <= m <= 100), 第二行有n个整数(1 ~100),表示初始序列,编号从1...n。接着是m行表示m条指令,每行共有2个用空格隔开的整数a b,(-50<= a <= 50), (1 <= b <= n)。
输出
对于每组数据,输出一个整数占一行,表示操作后的序列中的最大整数。
样例
输入
2 2 2 1 2 1 1 -1 2 3 4 1 5 6 1 1 1 1 0 1 -1 1
输出
4 6
答案;
#include<iostream>
using namespace std;
int main() {
int T;
cin >> T;
while (T) {
int n, m, a, b;
int arr[101];
cin >> n >> m;
//输入数据
for (int i = 1; i <= n; i++) {
cin >> arr[i];
}
//输入指令并处理数据
for (int i = 1; i <= m; i++) {
cin >> a >> b;
if (a > 0) {
arr[b] = arr[b] * 2;
}
else if (a < 0) {
arr[b] = arr[b] + 2;
}
else {
;
}
}
//找出最大值
int max = arr[1];
for (int i = 2; i <= n; i++) {
max = max > arr[i] ? max : arr[i];
}
cout << max << endl;
T--;
}
return 0;
}
分析:这个题第一眼看上去有点理不清题目,其实很简单,每组数据有两个参数n、m,n表示n个数据,m表示有m条指令。这m条指令是用来操作这n个数据的。这个题目本身不难,只是数据输入那里理清需要一点时间。
是否通过:
34007 - 高精度加法(经典题)
时间限制 : 1 秒
内存限制 : 128 MB
计算两个非负整数之和
输入
从键盘上输入两个非负整数,每个数占一行,每个数的位数不超过240
输出
输出只有一行为两个数之和。
样例
输入
12 13
输出
25
答案:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
//字符转为数字
inline int f(char c) {
switch (c) {
case '0':
case'\0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
}
}
int main() {
char a[300] = { 0 }, b[300] = { 0 }, sum[300] = { 0 };//数组a、b分别表示两个加数,sum表示和
cin >> a>>b;//输入数据
//逆序
int a_len = strlen(a);
int b_len = strlen(b);
for (int i = 0, j = a_len - 1; i < j; i++, j--) {
int tem = a[i];
a[i] = a[j];
a[j] = tem;
}
for (int i = 0, j = b_len - 1; i < j; i++, j--) {
int tem = b[i];
b[i] = b[j];
b[j] = tem;
}
//求出加数较大的位数
int max = a_len > b_len ? a_len : b_len;
int jw = 0,SUM=0;
int length = 0;
//高精度加法
for (int i = 0; i < max; i++) {
SUM = f(a[i]) + f(b[i])+jw;
jw = SUM / 10;
sum[i] = SUM % 10 + 48;//数字转为字符
length++;
}
//最高位进位不为0,则和的位数加1
if (jw != 0) {
sum[length] = jw + 48;
length++;
}
for (int i = length - 1; i >= 0; i--) {
cout << sum[i];
}
return 0;
}
分析:这道题有的人上来就是定义两个long long类型的数据进行加法,我可以明确告诉你,long long类型表示的范围也就才900亿亿多,对于高精度加法来说是完全不够的,比如进行两个人5000多位数的加法long long是完全不能进行的,范围有限。因此我们要回到小学的加法运算,如下:
就是从个位开始加,满10向高位进1,但是对计算机怎么计算呢??
首先,如果我们就按照字符串顺序存储的话会带来计算上的困难,不是说不可以,为了计算方便,我们把字符串逆序存储,比如123+789计算如下;
最后我们只需要把计算结果逆序输出就可以了。在这里我还要强调一下这个计算,比如计算999+998,如下:
当最高位还有进位时,此时结果位数多1,这种情况容易被忽略。
34008 - 奇怪的车牌号(走了弯路,建议再仔细看一下)
时间限制 : 1 秒
内存限制 : 128 MB
汽车的车牌号是一个8位数,最高位可以为0,所以车牌号范围为00000000到99999999。
有一辆汽车出了事故,司机驾车逃跑,有三位目击者向警方提供线索。
甲:车牌号的前4位是递增的自然数,如0 1 2 3 ,或1 2 3 4 ,…… 最多为6 7 8 9
乙:车牌号的后4位也是递增的自然数
丙:车牌号的数字和是某个整数的平方
例如:0 1 2 3 1 2 3 4就是满足上面的三个条件
0 1 2 3和1 2 3 4 均为递增的自然数,其数字和16为4的平方。
当然,满足上面的三个条件的车牌号还有许多,你的任务求出所有满足条件的车牌号个数。
输入
无
输出
一个整数,即满足条件的车牌号的个数。
样例
输入
输出
答案:
#include<iostream>
#include<math.h>
using namespace std;
int main() {
int i1, j1, k1, d1;//表示车牌号前4个数字
int i2, j2, k2, d2;//表示车牌号后4个数字
int count = 0;
for (int i = 0; i <= 6; i++) {
i1 = i;
j1 = i1 + 1;
k1 = i1 + 2;
d1 = i1 + 3;
for (int j = 0; j <= 6; j++) {
i2 = j;
j2 = i2 + 1;
k2 = i2 + 2;
d2 = i2 + 3;
int sum = i1 + j1 + k1 + d1 + i2 + j2 + k2 + d2;
//判断一个数是不是完全平方数
if (sqrt(sum) - (int)sqrt(sum) < 0.00001) {
count++;
}
}
}
cout << count << endl;
return 0;
}
分析:这个题要把握好前4位和后4位都是递增的自然数这个条件,不要把题目想的复杂了,其实题目意思很简单,只需要一个二重循环,因为第一个车牌号确定后,剩下的几个车牌号也就确定了,比如第一个车牌号是1,那么第二个只能是2,第三个只能是3,第四个只能是4.后面4个车牌号也是如此。(可以自己把满足条件的车牌号码打印出来)
是否通过:
34009 - 连续非素数的最长度
时间限制 : 1 秒
内存限制 : 128 MB
给出一个正整数n(2≤n≤1000000),例如n=30,在1,2,3,……30中,连续的非素数有
4 长度为1
6 长度为1
8 9 10 长度为3
12 长度为1
14 15 16 长度为3
18 长度为1
20 21 22 长度为3
24 25 26 27 28 长度为5
30 长度为1
其中,最大长度为5,即有连续的5个非素数。
输入
一个整数n
输出
一个整数,即连续非素数最大长度
样例
输入
12
输出
3
答案:
#include<iostream>
#include<math.h>
using namespace std;
bool isPrimeNumber(int N) {
if (N == 1) {
return false;
}
else if (N == 2) {
return true;
}
else {
for (int i = 2; i <= sqrt(N); i++) {
if (N % i == 0) {
return false;
}
}
return true;
}
}
int main() {
int N;
cin >> N;
int count = 1,max = 0;
bool constant = true;
for (int i = 2; i < N; i++) {
if (!isPrimeNumber(i) && !isPrimeNumber(i+1)) {
count++;
}
else {
max = max > count ? max:count;
count = 1;
}
}
max = max > count ? max : count;
cout << max << endl;
return 0;
}
分析:这篇博客这几道题都不是很难,除了那个高精度加法可能有点新颖以外,其他题目都不是很难,这个题目也是老生常谈的一个题目,就是找最大连续子段和,就是用一个变量max来记录当前找到的最大长度,之后再慢慢更新。
是否通过: