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