洛谷习题记录整理2

P1059 [NOIP2006 普及组] 明明的随机数

题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N N N 1 1 1 1000 1000 1000 之间的随机整数 ( N ≤ 100 ) (N\leq100) (N100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

输入格式

输入有两行,第 1 1 1 行为 1 1 1 个正整数,表示所生成的随机数的个数 N N N

2 2 2 行有 N N N 个用空格隔开的正整数,为所产生的随机数。

输出格式

输出也是两行,第 1 1 1 行为 1 1 1 个正整数 M M M,表示不相同的随机数的个数。

2 2 2 行为 M M M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

样例 #1

样例输入 #1

10
20 40 32 67 40 20 89 300 400 15

样例输出 #1

8
15 20 32 40 67 89 300 400

提示

NOIP 2006 普及组 第一题

提交答案

/*
	Name: P1059 [NOIP2006 普及组] 明明的随机数
	Copyright: 洛谷 
	Author: prayer 
	Date: 06/09/22 21:18
	Description: 
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
	int n,f,a[1005]={0};//因为本题输入是1-1000的整数,数据范围较小,因此对取值区间内的节点进行标记
	cin >> n;
	int num = n;
	for(int i=0;i<n;i++){
		cin >> f;
		if(a[f] == f) {
			num--;//当重复的输入值出现时,不必重复标记节点,并且将总数n减少,得到不重复的总数num
		}else{
			a[f] = f;//当输入的数字所对应的节点未被标记,则标记为输入的值
		}	
	}
	cout << num << endl;
	int k = 0;
	for(int i=0;i<1005;i++) {
		if(a[i] > 0) {
			cout << a[i] << " ";//遍历标记数组将标记过的节点值进行输出
			k++;//每输出一个被标记的数字,计数器k++
			if(k == num) break;//优化代码,当输出的计数器数量k与实际不重复的总数num相等时,则接下来的数组中应当没有被标记过的节点,直接退出当前循环
		}
	}
	cout << endl;
	return 0;
}

P1075 [NOIP2012 普及组] 质因数分解

题目描述

已知正整数 n n n 是两个不同的质数的乘积,试求出两者中较大的那个质数。

输入格式

输入一个正整数 n n n

输出格式

输出一个正整数 p p p,即较大的那个质数。

样例 #1

样例输入 #1

21

样例输出 #1

7

提示

1 ≤ n ≤ 2 × 1 0 9 1 \le n\le 2\times 10^9 1n2×109

NOIP 2012 普及组 第一题

提交答案

/*
	Name: P1075 [NOIP2012 普及组] 质因数分解
	Copyright: 洛谷 
	Author: prayer 
	Date: 07/09/22 18:30 
	Description: 
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
	int n,p;//输入的正整数n的范围是1-2000000000,因此只需要使用int即可,保险起见,也可使用long long
	cin >> n;//注意题目已知条件,正整数n是两个不同质数的乘积,因此不会出现类似于n=24,即n为合数这种情况,因此本题求n的因数中较大的质数,既可以理解为求最小的质因数,最后输出n/最小的质因数
	for(int i=2;i*i<=n;i++){//优化代码,求最小的质因数,因此不会超过n的开方
		if(n%i == 0) {
			p = n/i;//当n%i=0时意味着i就是最小的质因数,因此p就是最大的质因数
			break;//优化代码,当找到最小的质因数即可求得最大的质因数,因此不需要在进行循环,直接退出当前循环即可
		}
	}
	cout << p << endl;
	return 0;
}

P1085 [NOIP2004 普及组] 不高兴的津津

题目描述

津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。

输入格式

输入包括 7 7 7 行数据,分别表示周一到周日的日程安排。每行包括两个小于 10 10 10 的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。

输出格式

一个数字。如果不会不高兴则输出 0 0 0,如果会则输出最不高兴的是周几(用 1 , 2 , 3 , 4 , 5 , 6 , 7 1, 2, 3, 4, 5, 6, 7 1,2,3,4,5,6,7 分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。

样例 #1

样例输入 #1

5 3
6 2
7 2
5 3
5 4
0 4
0 6

样例输出 #1

3

提示

NOIP2004 普及组第 1 题

  • 2021-10-27:增加一组 hack 数据
  • 2022-06-05:又增加一组 hack 数据

提交答案

/*
	Name: P1085 [NOIP2004 普及组] 不高兴的津津
	Copyright: 洛谷
	Author: prayer
	Date: 07/09/22 21:29
	Description:
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
	int a,b,t[7];//a表示津津学校上课的时间,b表示津津课外学习的时间,数组t用于存放津津每天学习的总时间
	bool f = 0;//f用于标记津津是否开心,0为开心,1为不开心
	for(int i=0; i<7; i++) {
		cin >> a >> b;
		t[i] = a+b;
		if(t[i]-8 > 0) f = 1;//当一周内有一天津津的学习时间超过8小时,则为不开心,因此f为1
	}
	int max = 0;//max用于标记最不开心的那一天
	if(!f) cout << 0 << endl;//f=0(f为假)津津开心,输出0
	else {
		for(int i=0; i<7; i++) {
			if(t[i] > t[max]) max = i;//当(第i天的学习时长)比(标记为最不开心那一天max的学习时长)还要长时,将第i天设为最不开心的那一天
		}
		cout << max+1 << endl;//注意上述循环都是从0开始,因此输出第几天时应当+1输出
	}
	return 0;
}

P1089 [NOIP2004 提高组] 津津的储蓄计划

题目描述

津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 300 300 300 元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。

为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上 20 % 20\% 20% 还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于 100 100 100 元或恰好 100 100 100 元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。

例如 11 11 11月初津津手中还有 83 83 83 元,妈妈给了津津 300 300 300 元。津津预计 11 11 11月的花销是 180 180 180 元,那么她就会在妈妈那里存 200 200 200 元,自己留下 183 183 183 元。到了 11 11 11 月月末,津津手中会剩下 3 3 3 元钱。

津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。

现在请你根据 2004 2004 2004 1 1 1 月到 12 12 12 月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到 2004 2004 2004 年年末,妈妈将津津平常存的钱加上 20 % 20\% 20% 还给津津之后,津津手中会有多少钱。

输入格式

12 12 12 行数据,每行包含一个小于 350 350 350 的非负整数,分别表示 1 1 1 月到 12 12 12 月津津的预算。

输出格式

一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出 − X -X X X X X 表示出现这种情况的第一个月;否则输出到 2004 2004 2004 年年末津津手中会有多少钱。

注意,洛谷不需要进行文件输入输出,而是标准输入输出。

样例 #1

样例输入 #1

290
230
280
200
300
170
340
50 
90 
80 
200
60

样例输出 #1

-7

样例 #2

样例输入 #2

290 
230 
280 
200 
300 
170 
330 
50 
90 
80 
200 
60

样例输出 #2

1580

提交答案

/*
	Name: P1089 [NOIP2004 提高组] 津津的储蓄计划
	Copyright: 洛谷
	Author: prayer
	Date: 07/09/22 22:26
	Description:本题的思路就是模拟,模拟津津得到零花,存钱,花钱的过程
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
	int ys[12];//数组ys用于存放每个月的预算
	int mm = 0,jm = 0,f = -1;//mm表示存放到妈妈那的金钱,jm表示津津手上的零花钱,f用于标记是否出现不够预算的情况,当f=-1时,满足预算,当f!=-1时,表示不满足预算,并且将第几个月赋值给f
	double ans;//ans用于计算年末时,津津一共有多少钱
	for(int i=0; i<12; i++) {
		jm += 300;//津津每月会收到妈妈给的零花钱300元
		cin >> ys[i];//输入每月的预算
		int a = (jm-ys[i]) / 100;//判断零花前减去预算后还有没有超过整百
		if(a > 0) {
			mm += a*100;
			jm -= a*100;
		}//剩余零花钱超过整百,则存储在妈妈那的钱加上整百,津津的零花钱则减去整百
		jm -= ys[i];//到月底了,津津的零花钱按照预算的金额花掉了
		if(jm < 0 && f == -1) f=i;//判断津津本月月底时是否还有零花钱,本月零花钱不足并且以往都没有出现过零花不满足预算的情况下,将第i月赋值给f
	}
	if(f != -1) cout << "-" << f+1 << endl;//f被重新标记过,输出零花不足预算的月份,注意上述循环是从0开始,因此输出月份时要+1 
	else {
		ans = jm + mm*1.2;
		cout << ans << endl;//f没有被标记过,津津一共有的钱是(12月底津津手头存留的零花钱)+(存储在妈妈那的钱的1.2倍)
	}
	return 0;
}

P1116 车厢重组

题目描述

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 180 180 180 度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

输入格式

共两行。

第一行是车厢总数 N ( ≤ 10000 ) N( \le 10000) N(10000)

第二行是 N N N 个不同的数表示初始的车厢顺序。

输出格式

一个整数,最少的旋转次数。

样例 #1

样例输入 #1

4
4 3 2 1

样例输出 #1

6

提交答案

/*
	Name: P1116 车厢重组
	Copyright: 洛谷
	Author: prayer
	Date: 08/09/22 15:23
	Description:实现相邻两节车厢的位置交换实际上就是模拟冒泡排序的过程
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
	int n,a[10005];
	cin >> n;
	for(int i=0; i<n; i++) {
		cin >> a[i];
	}
	int ans = 0;
	for(int i=0; i<n; i++) {//模拟冒泡排序,外层循环控制循环的趟数
		for(int j=i+1; j<n; j++) {//内层循环控制每趟循环需要比较的次数
			if(a[i] > a[j]) ans++;//如果前一项车厢号比后一项车厢号大,按照冒泡排序需将前一项向右移,也就是要交换一次,因此交换次数ans+1
		}
	}
	cout << ans << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值