第四周测验

1. 角谷猜想

描述

所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘3加1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到1。如,假定初始整数为5,计算过程分别为16、8、4、2、1。 
程序要求输入一个整数,将经过处理得到1的过程输出来。

输入一个正整数N(N <= 2,000,000)输出从输入整数到1的步骤,每一步为一行,每一部中描述计算过程。最后一行输出"End"。如果输入为1,直接输出"End"。样例输入
5
样例输出
5*3+1=16
16/2=8
8/2=4
4/2=2
2/2=1
End
来源

代码:

#include<iostream>
#include<cstdio>
int main()
{
	long long n;
	scanf("%lld", &n);
	while(n != 1)
	{
		if(n % 2 == 1)
		{
			printf("%lld*3+1=%lld\n", n, n*3+1);
			n = n*3 + 1;
		}
		if(n % 2 == 0)
		{
			printf("%lld/2=%lld\n", n, n/2);
			n = n / 2;
		}
	}
	if(n==1) printf("End");
	return 0;	 
} 

【易错点】这里的n不能用int类型,否则会报错:Time Limit Exceeded。


2. 正常血压

描述

监护室每小时测量一次病人的血压,若收缩压在90 - 140之间并且舒张压在60 - 90之间(包含端点值)则称之为正常,现给出某病人若干次测量的血压值,计算病人保持正常血压的最长小时数。

输入第一行为一个正整数n,n < 100
其后有n行,每行2个正整数,分别为一次测量的收缩压和舒张压,中间以一个空格分隔。输出输出仅一行,血压连续正常的最长小时数。样例输入
4
100 80
90 50
120 60
140 90
样例输出
2
来源习题(5-6) 医学部 2010 期末试题 周恺【思路】本题主要注意更新最长时间。当有一次不符合条件,就要重新开始计时。
#include<iostream>
using namespace std;
int main()
{
	int n, a, b, time = 0, maxn = 0;
	cin >> n;
	while(n -- )
	{
		cin >> a >> b;
		if( (a >= 90 && a <= 140) && (b >= 60 && b <= 90))
		{
			++ time;
		}
		else 
			time = 0;
		if( time > maxn)
			maxn = time;
	}
	cout << maxn << endl;
	return 0;
}


3. 数字反转

描述

给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2)。

输入输入共 1 行,一个整数N。

-1,000,000,000 ≤ N≤ 1,000,000,000。输出输出共 1 行,一个整数,表示反转后的新数。样例输入
样例 #1:
123

样例 #2:
-380
样例输出
样例 #1:
321

样例 #2:
-83
来源NOIP201

【重点】

1. 高位的0不要;9800000   输出  89

2. 负号要保留;

3. 0这种特殊情况。

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	long long n;
	cin >> n;
	if (n==0)  cout << "0";
	if (n < 0) //将负数变为正数 
	{
		cout << "-";
		n = -n;
	} 	
	while(n%10 == 0)//去除高位的0 
	{
		n = n/10;
		if (n%10 != 0) break;		 
	}
	while (n)//倒着输出 
	{
		cout << n%10;
		n = n/10;
	}
	return 0;
}

#include<iostream>
using namespace std;
int main()
{
	int n, k = 0;//k一定要定义初始值 
	cin >> n;
	while (n)//相当于n!=0 
	{
		k = k*10 + n%10;
		n = n/10;
	}
	cout << k << endl;
	return 0;
} 


3. 求特殊自然数

描述

一个十进制自然数,它的七进制与九进制表示都是三位数,且七进制与九进制的三位数码表示顺序正好相反。编程求此自然数,并输出显示。

输入
无。
输出
三行:
第一行是此自然数的十进制表示;
第一行是此自然数的七进制表示;
第一行是此自然数的九进制表示。
样例输入
(无)
样例输出
(不提供)
  • 查看
    • 【思路】这个题要注意几个问题。
    • 1. 先枚举这3位数的十进制数,这个数的7、9、10进制都是3位数,因此应该将7、9进制的最小最大数都化为10进制进行计算,确定枚举范围。
    • 2. 假设好10进制数后,转为7(9)进制,用短除法一直求余,得到7(9)进制数;
    • 3. 利用7、9进制数的十进制数相等列等式,算出结果。

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	for(int i = 49; i <= 342; ++i)//7进制最大的数为666,化为10进制为342,枚举十进制数,i可以从100开始计算 
	{
		int n = i;//保证i不变 
		int p70 = n % 7;//十进制转为7进制 
		n/=7;
		int p71 = n % 7;
		n/=7;
		int p72 = n % 7;
		if (p70*81 + p71*9 + p72 == i)//这个数的7进制、九进制的十进制相同 
		{
			cout << i << endl;
			cout << p72 << p71 << p70 << endl;
			cout << p70 << p71 << p72 << endl;
			break;
		}	
	}
	return 0;	
} 


4. 雇佣兵

描述

雇佣兵的体力最大值为M,初始体力值为0、战斗力为N、拥有X个能量元素。

当雇佣兵的体力值恰好为M时,才可以参加一个为期M天的战斗期,战斗期结束体力值将为0。在同一个战斗期内,雇佣兵每连续战斗n天,战斗力就会上升1点,n为当前战斗期开始时的战斗力。

一个战斗期结束后,雇佣兵需要用若干个能量元素使其体力恢复到最大值M,从而参加下一个战斗期。每个能量元素恢复的体力值不超过当前的战斗力。每个能量元素只能使用一次。

请问:雇佣兵的战斗力最大可以到达多少。

输入
一行包括三个整数M、N、X,相邻两个整数之间用单个空格隔开。M、N、X均为不超过10000的正整数。
输出
输出一个整数,为雇佣兵的最大战斗力。
样例输入
5 2 10
样例输出
6

#include<iostream>
using namespace std;
int main()
{
	int M, N, X;
	cin >> M >> N >> X;
	while(X > 0)
	{
		int t = M / N;
		if(M % N) ++t;
		if(X < t) break;
		X -= t;
		t = M / N;
		N += t;
	}
	cout << N << endl;
	return 0;
} 

本题暂时未理解题意,只有部分数据通过了,估计是哪里没想到~后面更新。求余这里没想通。

现在来更新啦~

之前题目看错了,每个能量元素恢复的体力值不超过当前的战斗力。 也就是每个能量最多能恢复N个体力值,就需要(M/N + t)个能量。t=0或1.

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
	int M, N, X, t = 0;
	cin >> M >> N >>X;
	while(X > 0)
	{
		if(M % N != 0) 
			t = 1;
		else 
			t = 0;
		if(X < (M / N) + t) break;
		X = X - (M / N + t);
		N = M / N + N;	
	//	cout << M << " " << N << " "<< X << endl;
	}
	cout << N << endl;
	return 0;
}


5. 数字统计

描述

请统计某个给定范围[L, R]的所有整数中,数字2出现的次数。

比如给定范围[2, 22],数字2在数2中出现了1次,在数12中出现1次,在数20中出现1次,在数21中出现1次,在数22中出现2次,所以数字2在该范围内一共出现了6次。

输入输入共 1 行,为两个正整数 L 和 R,之间用一个空格隔开。输出输出共 1 行,表示数字 2 出现的次数。样例输入
样例 #1:
2 22

样例 #2:
2 100
样例输出
样例 #1:
6

样例 #2:
20
来源NOIP2010复赛 【思路】枚举每一个数,用求余得到每一位数,如果是2,就计数。
#include<iostream>
using namespace std;
int main()
{
	int l, r, count=0;
	cin >> l >> r;
	for(int i=l; i<=r; ++i)
	{
		int n = i;//这一步必不可少,否则无法输出结果 
		while (n)
		{
			if(n%10==2) ++count;
			n = n/10;
		}		
	}
	cout << count << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanyanwenmeng/article/details/81036163