“计算机程序设计能力考试(乙级)”真题刷题(六)

“计算机程序设计能力考试(乙级)”真题刷题

二十六、题目:1026 程序运行时间 (15 分)

要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间单位是 clock tick,即“时钟打点”。同时还有一个常数 CLK_TCK,给出了机器时钟每秒所走的时钟打点数。于是为了获得一个函数 f 的运行时间,我们只要在调用 f 之前先调用 clock(),获得一个时钟打点数 C1;在 f 执行完成后再调用 clock(),获得另一个时钟打点数 C2;两次获得的时钟打点数之差 (C2-C1) 就是 f 运行所消耗的时钟打点数,再除以常数 CLK_TCK,就得到了以秒为单位的运行时间。

这里不妨简单假设常数 CLK_TCK 为 100。现给定被测函数前后两次获得的时钟打点数,请你给出被测函数运行的时间。

输入格式:

输入在一行中顺序给出 2 个整数 C1 和 C2。注意两次获得的时钟打点数肯定不相同,即 C1 < C2,并且取值在 [0,10 ​7​​
]。

输出格式:

在一行中输出被测函数运行的时间。运行时间必须按照 hh:mm:ss(即2位的 时:分:秒)格式输出;不足 1 秒的时间四舍五入到秒。

输入样例:

123 4577973

输出样例:

12:42:59

1.代码

#include<iostream>
using namespace std;
int main() {
    int c1, c2;
    cin >> c1 >> c2;
    int time = (c2 - c1 + 50) / 100;
    int h, m, s;
    s = time % 60;
    h = time / 3600;
    m = (time - 3600 * h) / 60;
    printf("%02d:%02d:%02d", h, m, s);
    return 0;

}

2.心得

**printf()**真的很实用呢,千万要熟悉使用

二十七、题目:1027 打印沙漏 (20 分)

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

、 *****
、 ***
、 *
、 ***
、*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

19 *

输出样例:

、*****
、 ***
、 *
、 ***
、*****
2

1.代码

妈耶,测试点2过不了,不知道哪里出错,来个大佬帮俺看一下吧~

#include<iostream>
#include<iomanip>
using namespace std;
int main() {
	int n;
	char c;
	int i = 0; //记录需要构成三角形最小层次
	cin >> n >> c;
	int index = 0; //控制每行输出首个数时,前面需要空多少个空格。从0开始
	int flat = 1; //处理首个有空格情况。1代表通过setw(index)输出每行的第一个,-1代表直接输出该行的剩余数
	int sum = 0; //记录总共输出的c有多少个,如果不等于n就输出(n-sum)
	while (1) {

		//这里公式下面有给出解释
		if (2 * i * i == n + 1) 
			break;

		else if (2 * i * i > n + 1) {
			i--; //大于就说明出现不足,i需要减去1再break才是满足的。这里就是为什么需要分开写
			break;
		}
		i++;
	}

	//处理上三角
	for (int j = i; j>0; j--) { //这里是逆序打印 7 5 3 1..

		int t = 2*j-1; //每层的*都为奇数个,首项为1,通项公式为2n-1

		while (t >0){ //while循环输出每层的*
			if (flat ==1) { 
				index++; //index更新
				cout << setw(index) << c;
				sum++; //sum更新
			}
			else if (flat == -1) {
				cout << c;
				sum++;
			}
			flat = -1; //flat更新
			t--;
		}
			cout << endl; //过段,进入下一层,重复过程
			flat = 1; //flat更新
	}
	//处理下三角,同理跟上三角一样
	for (int j = 1; j < i; j++) { //这里是顺序打印 3 5 7...
		int t = 2 * j+1; //不同在这里,这里首项为3,所以通项公式为2n+1

		while (t > 0) {
			if (flat == 1) {
				index--;
				cout << setw(index) << c;
				sum++;
				
			}
			else if (flat == -1) {
				cout << c;
				sum++;
			}
			flat = -1;
			t--;
		}
			cout << endl;
		    flat = 1;
	}

	if (sum != n) //检查是否有剩余的数
		cout << n - sum << endl;
	
	system("pause");
	return 0;
}

补充:公式的解释如下
公式解释

2.心得

这道题蛮恶心的,格式化输出就是令人作恶。

二十八、题目:1028 人口普查 (20 分)

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入格式:

输入在第一行给出正整数 N,取值在(0,10​5 ];随后 N 行,每行给出 1 个人的姓名(由不超过 5 个英文字母组成的字符串)、以及按
yyyy/mm/dd(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。

输出格式:

在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。

输入样例:

5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

输出样例:

3 Tom John

1.代码

原链接这里轻点进入。

#include <iostream>
#include <string.h>
using namespace std;

const char maxInputBirth[11] = "2014/09/06";
const char minInputBirth[11] = "1814/09/06";

int main() {
    int n, count = 0;
    char name[6], birth[11];
    char maxName[6], minName[6];
    char maxBirth[11] = "2014/09/06", minBirth[11] = "1814/09/06";
    cin >> n;
    while (n--) {
        cin >> name >> birth;
        if (strcmp(maxInputBirth, birth) >= 0 && strcmp(minInputBirth, birth) <= 0) {
            count++;
            if (strcmp(maxBirth, birth) > 0) {
                strcpy(maxName, name);
                strcpy(maxBirth, birth);
            }
            if (strcmp(minBirth, birth) < 0) {
                strcpy(minName, name);
                strcpy(minBirth, birth);
            }
        }
    }
    cout << count;
    if (count > 0)
        cout << " " << maxName << " " << minName;
    return 0;
}


2.心得

咱也不知道为什么代码在Visul Studio运行不了,咱也不敢问。

二十九、题目:1029 旧键盘 (20 分)

旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。

输入格式:

输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过 80 个字符的串,由字母 A-Z(包括大、小写)、数字
0-9、以及下划线 _(代表空格)组成。题目保证 2 个字符串均非空。

输出格式:

按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有 1 个坏键。

输入样例:

7_This_is_a_test
_hs_s_a_es

输出样例:

7TI

1.代码

#include<iostream>
#include<string.h>
using namespace std;
const int N = 200;
int s[N];
int main()
{
	string a, b;
	cin >> a;
	cin >> b;
	for (int i = 0; i < b.size(); i++)
	{
		s[b[i]]++;
	}
	for (int i = 0; i < a.size(); i++)
	{
		if (s[a[i]] == 0)
		{
			s[a[i]]++;
			if (a[i] >= 'a' && a[i] <= 'z')
			{
				a[i] = a[i] - 32;
			}
			else if (a[i] >= 'A' && a[i] <= 'Z')
			{
				s[a[i] + 32]++;
			}
			s[a[i]]++;
			cout << a[i];
		}
	}
	system("pause");
	return 0;
}

2.心得

注意大小写字母互换!!!

三十、题目:1030 完美数列 (25 分)

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(≤10​5​​ )是输入的正整数的个数,p(≤10​9​​ )是给定的参数。第二行给出 N
个正整数,每个数不超过 10​9​​ 。

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

10 8

2 3 20 4 5 1 6 7 8 9

输出样例:

8

1.代码

测试点4过不了,妈耶,找不到,希望有个有缘人指出来,我TM直接跪下来感谢你。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
int main() {

	long N, p;
	cin >> N >> p;
	vector<long> v;
	long digit;
	int count = 0;

	for (int i = 0; i < N; i ++) {
		cin >> digit;
		v.push_back(digit);
	}

	sort(v.begin(), v.end()); //排好序,从小到大
	reverse(v.begin(), v.end()); //翻转,变为从大到小

	for (int i = 0; i < N; i++) {

		if (v[0] > v[i]*p)
			break;
		count++;
	}
	cout << count;
	system("pause");
	return 0;
}

但是发现了一个老哥代码实现思路跟我差不多,但是还是看不出我哪里有问题。。。这是链接

他的代码:

#include <iostream>
#include <algorithm>
using namespace std;
int main(){
    long n,p;
    cin>>n>>p;
    long a[n];
    int maxc=0;
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    int cnt=0;
    for(int i=0;i<n;i++){
        int j=cnt;
        while(j++<n)
            if(a[j]>a[i]*p)
                break;
        maxc=max(maxc,j-i);
        cnt=j;
    }
    cout<<maxc<<endl;
    return 0;
}

2.心得

本题不难,基本是平时经常遇到的题型,就是细节有问题,只能好好琢磨。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值