程序设计与算法(一)第4周测验(2020春季)

001:角谷猜想

  • 总时间限制: 1000ms 内存限制: 65536kB

描述

  • 所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘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

思考

AC

#include <iostream>
using namespace std;
int main(){
    long long N;	//注意范围
    scanf("%d",&N);
    while (N != 1){
        if (N%2 == 0){	//偶数
            cout << N << "/2=" << N/2 << endl;	//这题有毒,不能用printf()通过
            N /= 2;
        }else{
            cout << N << "*3+1=" << N*3+1 << endl;
            N = N*3+1;
        }
    }
    printf("End\n");
    return 0;
}

002:正常血压

  • 总时间限制: 1000ms 内存限制: 65536kB

描述

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

输入

  • 第一行为一个正整数n,n < 100
  • 其后有n行,每行2个正整数,分别为一次测量的收缩压和舒张压,中间以一个空格分隔。

输出

  • 输出仅一行,血压连续正常的最长小时数。

样例输入

4
100 80
90 50
120 60
140 90

样例输出

  • 2

思考

  • no

AC

#include <iostream>
int main(){
	int i,n,sum=0,p,q,max=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d %d",&p,&q);
		if((p>=90&&p<=140)&&(q>=60&&q<=90)){
			sum++;	//正常则计数
			if(sum>max){
				max=sum;	//记录小时数 
			} 
		}else	sum=0;		
	}
	printf("%d\n",max);
	return 0;
}

003:数字反转

  • 总时间限制: 1000ms 内存限制: 65536kB

描述

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

输入

  • 输入共 1 行,一个整数N。
  • -1,000,000,000 ≤ N≤ 1,000,000,000。

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

  • 123

样例 #2:

  • -380

样例输出
样例 #1:

  • 321

样例 #2:

  • -83

AC

#include <iostream>
using namespace std; 
int main(){
	long long n,m=0;
	scanf("%lld",&n);
	if(n<0){
		printf("-");	//输出负号 
		n=-n;	//取正 
	}	
	while(n!=0){
		m=m*10+n%10;	////原数个位相当于新数最高位
		n /= 10;	//整除10,相当于删除个位
	}
	printf("%lld\n",m);
	return 0;
} 

004:求特殊自然数

  • 总时间限制: 1000ms 内存限制: 65536kB

描述

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

输入

  • 无。

输出

  • 三行:
  • 第一行是此自然数的十进制表示;
  • 第二行是此自然数的七进制表示;
  • 第三行是此自然数的九进制表示。
样例输入
(无)
样例输出
(不提供)

思考

  • 看到这道题,第一想法是数组,但又觉得太麻烦了,就打算试试直接弄,结果🆗
  • 直接化七进制或九进制,先思考一下可能的七进制或九进制的三位数的范围,最小的数是七进制的(101)7,最大是九进制的(666)9,
  • 再根据题意“七进制与九进制的三位数码表示顺序正好相反”进行枚举即可。

AC

#include <iostream>
using namespace std;
int main(){
	int i,x,y,z;
	for(i=100;i<667;i++){
		x=i/100;	//百位 
		y=i/10%10;	//十位 
		z=i%100;	//个位 
		if(x*7*7+y*7+z==z*9*9+y*9+x){
			printf("%d\n",x*7*7+y*7+z);
			printf("%d%d%d\n",x,y,z);
			printf("%d%d%d\n",z,y,x);
		}
	}
	return 0;
}

005:雇佣兵

  • 总时间限制: 1000ms 内存限制: 65536kB

描述

  • 雇佣兵的体力最大值为M,初始体力值为0、战斗力为N、拥有X个能量元素。
  • 当雇佣兵的体力值恰好为M时,才可以参加一个为期M天的战斗期,战斗期结束体力值将为0。在同一个战斗期内,雇佣兵每连续战斗n天,战斗力就会上升1点,n为当前战斗期开始时的战斗力。
  • 一个战斗期结束后,雇佣兵需要用若干个能量元素使其体力恢复到最大值M,从而参加下一个战斗期。每个能量元素恢复的体力值不超过当前的战斗力。每个能量元素只能使用一次。
  • 请问:雇佣兵的战斗力最大可以到达多少。

输入

  • 一行包括三个整数M、N、X,相邻两个整数之间用单个空格隔开。M、N、X均为不超过10000的正整数。

输出

  • 输出一个整数,为雇佣兵的最大战斗力。

样例输入

  • 5 2 10

样例输出

  • 6

思考

  • 体力的初始值是0,但是有能量元素,x>0,需要用能量元素恢复体力才能进行战斗。因此可以用一个while循环
  • 当体力达到最大值M时,就进行为期M天的战斗。如果m>n,则n+=m/n,这时能量元素x-=m/n;如果m<n,直接输出n。
  • 战斗结束后,体力值为0,用能量元素进行恢复。如果当前的能量元素小于所需的能量元素,即x<m/n,则直接输出n。
  • 一直循环,直到能量元素用完。

AC

#include <iostream>
using namespace std;
int main(){
	int M,X,N,num=0; 
	scanf("%d %d %d",&M,&N,&X);//体力,战斗力、能量元素	
	while(X>0){
		if(M%N==0)	//消耗能源元素 
			num=M/N;
		else
			num=M/N+1;
		if(X<num)	break;
		X -= num;
		N += M/N;	//战斗		
	} 
	printf("%d\n",N);
	return 0;
} 

006:数字统计

  • 总时间限制: 1000ms 内存限制: 65536kB

描述

  • 请统计某个给定范围[L, R]的所有整数中,数字2出现的次数。
  • 比如给定范围[2, 22],数字2在数2中出现了1次,在数12中出现1次,在数20中出现1次,在数21中出现1次,在数22中出现2次,所以数字2在该范围内一共出现了6次。

输入

  • 输入共 1 行,为两个正整数 L 和 R,之间用一个空格隔开。

输出

  • 输出共 1 行,表示数字 2 出现的次数。

样例输入

样例 #12 22

样例 #22 100

样例输出

样例 #16

样例 #220

思考

  • 枚举+取余+判断

AC

#include <iostream>
using namespace std;
int main(){
	int L,R,i,num=0,j;
	scanf("%d %d",&L,&R);
	for(i=L;i<=R;i++)	//枚举范围 
		for(j=i;j>0;j=j/10)	 
			if(j%10==2) num++;	//判断是否为2 
	printf("%d\n",num);
	return 0;
}

第四周全部题解,🆗。

posted @ 2020-03-10 18:07  subeiLY  阅读(1563)  评论(0编辑  收藏  举报