OJ刷题 第十七篇

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来记录当前找到的最大长度,之后再慢慢更新。

是否通过: 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值