OJ刷题 第十二篇

21308 - 特殊的三角形

时间限制 : 1 秒

内存限制 : 128 MB

有这样一种特殊的N阶的三角形,当N等于3和4时,矩阵如下:

请输出当为N时的三角形。

输入

输入有多组数据,每行输入一个正整数N,1<=N<=100

输出

按照给出的样例进行输出

样例

输入

3

输出

1 2 6
3 5
4

 答案:

#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
	int a[101][101] = { 0 };
	int ret = 1;//给每个元素赋值的变量
	bool direction = false;//true表示往下走,false表示往上走
	int i = 1,N;
	while (scanf("%d",&N)==1) {
		ret = 1;
		direction = false;
		//计算三角形的值
			for (int i = 1; i <= N; i++) {
				if (direction) {//当前往下走
					int col = i;
					for (int k = 1; k <= i; k++) {
						a[k][col--] = ret++;
					}
					direction = !direction;//改变方向
				}
				else {//往上走
					int col = i;
					for (int k = 1; k <= i; k++) {
						a[col--][k] = ret++;
					}
					direction = !direction;//改变方向
				}
			}

		//打印
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N - i + 1; j++) {//每行元素有N-i+1个元素
				cout << a[i][j] << ' ';
			}
			cout << endl;
		}
	}
	return 0;
}

分析:这个题难度还是比较大的,之前我们在前面刷到过那个蛇形矩阵,那个题在前面也挺难的,但是我们理解整个代码逻辑后其实也没那么难,初次遇到这个题那肯定挺难的。这个题就是类似于这种:如图:

就是像一个蛇一样来回走。因此我们可以设置一个标记用来表示蛇是往下走还是往上走。每次走完后改变当前方向。至于每个方向是怎么走的,这个就自己去琢磨了。

 另外这个题输入的数据个数是任意的,最开始我写的是这样:

while (true) {
		cin >> N;

就陷入死循环,代码不通过,提示输出超限!后面还是借助C语言的scanf函数的输入来输入,后面就能通过了。这个题这样出,用C/C++还是不好实现的,因为这种任意数据的输入,而且还不知道输入什么表示结尾,这种输入用C/C++实现比较困难!。

最后是否通过:

21204 - 图书管理员(NOIP2017PJT2)

时间限制 : 1 秒

内存限制 : 128 MB

图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个正整数。 每位借书的读者手中有一个需求码,这个需求码也是一个正整数。如果一本书的图书编码恰好以读者的需求码结尾,那么这本书就是这位读者所需要的。

小D刚刚当上图书馆的管理员,她知道图书馆里所有书的图书编码,她请你帮她写一个程序,对于每一位读者,求出他所需要的书中图书编码最小的那本书,如果没有他需要的书,请输出-1。

输入

输入文件的第一行,包含两个正整数 n 和 q,以一个空格分开,分别代表图书馆里书的数量和读者的数量。 接下来的 n 行,每行包含一个正整数,代表图书馆里某本书的图书编码。 接下来的 q 行,每行包含两个正整数,以一个空格分开,第一个正整数代表图书馆里读者的需求码的长度,第二个正整数代表读者的需求码。 数据范围:1 ≤ n ≤ 1,000,1 ≤ q ≤ 1,000,所有的图书编码和需求码均不超过 10,000,000。

输出

输出文件有 q 行,每行包含一个整数。 如果存在第 i 个读者所需要的书,则在第 i 行输出第 i 个读者所需要的书中图书编码最小的那本书的图书编码;否则输出-1。

样例

输入

5 5 
2123 
1123 
23 
24 
24 
2 23 
3 123 
3 124 
2 12 
2 12

输出

23 
1123 
-1 
-1 
-1

答案:

#include<iostream>
typedef struct reader {//读者信息,包括所需编号长度和末尾的编号
	int length;
	int code;
}reader;

int calcute(int length, int book) {//计算某本书末尾长度为length的值,如2232末尾长度为2的值是32
	int sum = 0;
	int r = 1,mul=1;
	for (int i = 1; i <= length; i++) {
		r = book % 10;;
		sum = sum + mul*r;
		mul *= 10;
		book /= 10;
	}
	return sum;
}
using namespace std;
int main() {
	int n_book, q_read;//分别表示书的数量和读者的数量
	cin >> n_book >> q_read;
	int book[1000];//存放书的编号
	reader people[1000];//存放读者信息
	//输入书的编码
	for (int i = 0; i < n_book; i++) {
		cin >> book[i];
	}
	//输入读者的数据
	for (int i = 0; i < q_read; i++) {
		cin >> people[i].length >> people[i].code;
	}
	//求最大编号的书
	int max=book[0];//求最大编号是为了找最小编号,仔细琢磨
	for (int i = 1; i < n_book; i++) {
		max = max > book[i] ? max : book[i];
	}
	//对每一位读者找编号最小的那本书
	for (int i = 0; i < q_read; i++) {
		int min=max;
		bool flag = false;
		for (int j = 0; j < n_book; j++) {
			if (calcute(people[i].length, book[j])==people[i].code) {
				min = min > book[j] ? book[j] : min;
				flag = true;
			}
		}
		if (flag) {
			cout << min << endl;
		}
		else {
			cout << -1 << endl;
		}
	}
	return 0;
}

 分析:这个题给的信息有点多,要仔细梳理,文字多不要害怕,往往文字多,题目逻辑是很简单的。这到题的意思就是对每一个读者,每一位读者给出了编号得长度和指定得编号,现在就是要去和每本书作比较,取出每本书指定长度的末尾,然后和读者给出的编号比较,如果一样,就保存当前书的编号,继续对比,直到所有书对比完,找到最小那个编号即可,如果没有符合条件的编号,打印-1即可。

这道题难点:

1、在存读者的信息用到了结构体,当然你也可以用两个数组存储,但是为了体现出读者信息的整体性,用结构体还是比较好。这是难的一个点。

2、其次就是这道题我们要通过最大编号找最小编号。这个可能不好理解。当然用两个数组存读者信息的话也用不到这个。

是否通过:

21401 - 进制转换

时间限制 : 1 秒

内存限制 : 128 MB

给定一个十进制正整数N(1 ≤ N ≤ 30000),求其对应的二进制数。

输入

仅一行,包含一个正整数N。

输出

共一行,包含一个正整数,表示N对应的二进制数。

样例

输入

10

输出

1010

 答案:

#include<iostream>
using namespace std;
int main() {
	int N;
	cin >> N;
	int num = N;
	int a[16];//题目说N最大为30000,故二进制数最多不超过16位
	int i = 0,count = 0;
	while (num) {
		int r = num % 2;
		a[i++] = r;
		count++;
		num /= 2;
	}
	if (N == 0) {
		cout << N << endl;
	}
	else {
		for (int i = count - 1; i >= 0; i--) {
			cout << a[i];
		}
	}
	return 0;
}

分析:当N为0时到单独处理,我们用短除法把十进制数获得余数,采取倒取余数的方式获得它的二进制数。其实也可以可以采用栈来实现。栈的一个应用可以用来实现进制转换。

是否通过:

21403 - 间谍

时间限制 : 1 秒

内存限制 : 128 MB

现在有9个科学家正在一起研究机密问题,但据可靠消息,其中有两人是间谍,只有7个人是真正的科学家。cyh同学想将这两个间谍揪出来。当然,这9人都声称自己不是间谍。幸运的是,每个人都戴着一顶帽子,帽子上有一个小于100的正整数。根据最新的准确消息,真正的7位科学家戴着的帽子上的数字之和刚好等于100。由于cyh同学要准备期终考试,请你编写一个程序,找出真正的7个科学家。

输入

输入共9行。

每行一个整数,第i行的整数表示第i个科学家戴的帽子上的正整数。

输出

输出共7行(因为只有7个科学家)。

每行一个整数,第i行的整数表示第i个科学家戴的帽子上的正整数,注意输出的顺序是按去掉两个间谍后的顺序。

样例

输入

1
5
6 
7 
10 
12 
19 
29 
33

输出

1
5
6 
7 
19 
29 
33

答案:

#include<iostream>
using namespace std;
int main() {
	int a[9];
	int sum = 0;
	for (int i = 0; i < 9; i++) {
		cin >> a[i];
		sum += a[i];
	}
	sum -= 100;//则sum的值为不是科学家的两个人帽子之和
	//找出符合条件的两个人
	for (int i = 0; i < 9; i++) {
		for (int j = 1; j < 9; j++) {
			if (a[i] + a[j] == sum) {
				a[i] = 0;
				a[j] = 0;
				break;
			}
		}
	}
	//打印
	for (int i = 0; i < 9; i++) {
		if (a[i]) {
			cout << a[i] << endl;
		}
	}
	return 0;
}

 分析:这个题意思就是在9个数中找出7个数,使得它们的和为100,剩下的两个数字肯定就是间谍。但是现在怎么把所有的7种组合找出来呢?用9重循环???我想这不好办吧。这道题我们反其道而行之。既然是求求7个等于100的数字,我们可以把9个数字加起来然后减去100,得到的结果就是间谍之和,间谍就两个,只需两个循环即可

是否通过:

 

21405 - 哪种苹果最多

时间限制 : 1 秒

内存限制 : 128 MB

陶陶家的院子里有许多苹果树,每到秋天树上就会结出许多苹果。苹果成熟的时候,陶陶就会跑去摘苹果。经过估算,每个苹果都有一个甜度,第i个苹果的甜度为di。

输入

输入共有两行:

第一行,包含一个整数n,表示有n个苹果;

第二行,包含n个用空格隔开的正整数,分别表示n个苹果的甜度。

对于100%的数据,1≤di≤1000;1≤n≤100。

输出

输出共一行,包含两个用空格隔开的整数,分别表示最多的那种苹果的甜度及有几个这样的苹果。

样例

输入

10
100 200 200 140 129 134 167 198 200 110

输出

200 3

答案:

#include<iostream>
using namespace std;
int main() {
	int n;
	cin >> n;
	int di[100];
	for (int i = 0; i < n; i++) {
		cin >> di[i];
	}
	//找出甜度不同的苹果的有多少个
	int kind[100] = { 0 };
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (di[i] == di[j]) {
				kind[i]++;
			}
		}
	}

	//求出不同甜度的苹果的个数,求出最大的那个个数
	int max = kind[0];
	int maxDI = di[0];//求出甜度最大的苹果
	for (int i = 0; i < n; i++) {
		if (max <= kind[i]) {
			max = kind[i];
		}
		maxDI = maxDI > di[i] ? maxDI : di[i];
	}
	//甜度个数相同的苹果,求出甜度小的那个
	int min = maxDI;
	for (int i = 0; i < n; i++) {
		if (max == kind[i]) {
			min = min < di[i] ? min : di[i];
		}
	}
	cout << min << ' ' << max << endl;
	return 0;
}

分析:这道题和前面那道21404-最好吃的苹果相比,难度大了一些。另外这个题有一个条件它没说清楚,当不同的甜度有相同的的苹果个数且都是最多时,要选出甜度最小的那个,这是题目没有说明的地方,我也是通过它的测试案例才知道题目少了这个条件

是否通过:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值