NPU寒假练习

A- 校门外的树

题目描述

  • 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
    马路上有一些区域要用来建地铁,这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

Input

  • 输入的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

Output

  • 输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
Sample Input
  • 500 3
    150 300
    100 200
    470 471
Sample Output
  • 298
题解
  • 这道题目就是简单地通过遍历每一条地铁起点与终点之间的每一个整数点,用flag数组保存每个位置树的状态来判断树的数量是否需要减少。
#include<iostream>
using namespace std;
int flag[10005];
int main(){
	int n=0,m=0;
	cin>>n>>m;
	int i=0;
	int cnt=0;
	while(n+1){
		flag[i]=1;
		i++;
		n--;
		cnt++;
	}
	int a=0,b=0;
	while(m){
		cin>>a>>b;
		for(int j=a;j<=b;j++){
			if(flag[j]){//当flag数组中的数字为1时表示该位置的树依然存在,此时将树的数量减一并将该位置作为下标的数组元素置为0.
				cnt--;
				flag[j]=0;
			}
		}
		m--;
	}
	cout<<cnt;
	return 0;
}

B - 铺地毯

题目描述

  • 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n张地毯,编号从 1 到n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
    地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。

    img

Input

  • 输入共 n+2行。
    第一行,一个整数 n,表示总共有 n张地毯。
    接下来的 n行中,第 i+1行表示编号 i的地毯的信息,包含四个正整数 a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标(a,b)以及地毯在 x轴和 y轴方向的长度。
    第 n+2 行包含两个正整数 x 和 y,表示所求的地面的点的坐标(x,y) 。

Output

  • 输出共 1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出-1。

Sample Input

  • 3 
    1 0 2 3 
    0 2 3 3 
    2 1 3 3  
    2 2 
    

Sample Output

  • 3 
    

题解

  • 这道题先使用结构体数组保存每一个地毯的信息,对于目标位置,由于题目要求输出覆盖在该点最上面一层的地毯标号,因此在遍历地毯的过程中,从最后一个地毯开始向前遍历,
#include<iostream>
using namespace std;
struct place{
	int numx;
	int numy;
	int lenx;
	int leny;
};
int main(){
	struct place p[10005];
	int n;
	cin>>n;
	int cnt=0;
	while(n){
	cin>>p[cnt].numx>>p[cnt].numy>>p[cnt].lenx>>p[cnt].leny;
		n--;
		cnt++;
	}
	int pa,pb;
	cin>>pa>>pb;
	for(int i=cnt;i>0;i--){
		if((pa>=p[i-1].numx&&pa<=p[i-1].lenx+p[i-1].numx)&&(pb>=p[i-1].numy&&pb<=p[i-1].leny+p[i-1].numy)){
			cout<<i;//判断符合条件时直接输出地毯编号
			return 0;
		}
	}
 	cout<<-1;
	return 0;
}

D - IP地址转换

题目描述

  • IP地址总是由4个0-255的数字以"."隔开的形式来显示给用户,例如192.168.0.1。在计算机中,一个IP地址用4字节来依次存储其从右到左的4个数字部分,每个字节(8比特)以2进制的形式存储相应的IP地址数字,请你实现一个从IP地址的显示格式到计算机存储格式的转换。

Input

  • 每行输入一个IP地址,如果输入为-1,结束输入

Output

  • 每行输出一个IP地址在计算机存储中以二进制表示的4字节内容
Sample Input
  • 192.168.0.1
    255.255.0.0
    1.0.0.1
    -1
    
Sample Output
  • 11000000101010000000000000000001
    11111111111111110000000000000000
    00000001000000000000000000000001
    

题解

  • 由于题目已经给出IP地址的组成形式,因此分别将每个IP地址的四个十进制数转化成二进制数并保存在数组中,最终输出即可。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int k[10005][10];
int n[10005][5];
void ejz(int a,int i,int j);
int main(){
	int i=0;
	int j=0;
	int g=0;
	int cnt=0;
	char q;
	r:
	scanf("%d.%d.%d.%d",&n[g][0],&n[g][1],&n[g][2],&n[g][3]);  
	if(n[g][0]!=-1){
		cnt++;
		ejz(n[g][0],i,j);
		i++;
		ejz(n[g][1],i,j);
		i++;
		ejz(n[g][2],i,j);
		i++;
		ejz(n[g][3],i,j);
		i++;
		g++;
		goto r;
	}
	for(int p=0;p<cnt*4;p++){
			for(int y=1;y<=8;y++){
				cout<<k[p][y];
			}	
			if((p+1)%4==0) cout<<endl;
	}
	return 0;
}
void ejz(int a,int c,int d){
	q:
			int num=a%2;
			k[c][8-d]=num;
			d++;
			a/=2;
			if(!a){
			return;
		}
		else{
			goto q;
		}
			return ;
} 

E - 明明的随机数

题目描述

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

输入格式

  • 输入有 2 行,第 1 行为 1 个正整数,表示所生成的随机数的个数:N第 2 行有 N个用空格隔开的正整数,为所产生的随机数。

输出格式

  • 输出 2行,第 1 行为 1 个正整数 M,表示不相同的随机数的个数。第 2行为 M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
Sample Input
  • 10
    20 40 32 67 40 20 89 300 400 15
    
Sample Output
  • 8
    15 20 32 40 67 89 300 400
    

题解

  • 这道题目实际上要求输出的是输入数据中不重复数字的个数,并将这些数字按照升序排序后输出,在输入过程中同时记录不重复的数字个数,之后直接利用sort函数进行排序,比较容易。
#include<iostream>
#include<algorithm>
using namespace std;
int a[105];
int flag[1005];//对已经出现的数字进行标记
int main(){
	int n;
	cin>>n;
	int cnt=0;
	for(int i=1;i<=n;i++){
		cnt++;
		cin>>a[cnt];
		if(flag[a[cnt]]) {
			cnt--;
		}
		else{
			flag[a[cnt]]=1;
		}
	}
	cout<<cnt<<endl;
	sort(a+1,a+cnt+1);
	int j=1;
	while(cnt){
		cout<<a[j]<<" ";
		j++;
		cnt--;
	}
}

F - 拼数

题目描述

  • 设有 n 个正整数(n≤20),将它们联接成一排,组成一个最大的多位数。

    例如:n=3 时,3 个整数 13,312,343 联接成的最大整数为:34331213。

    又如:n=4 时,4 个整数 7,13,4,246 联接成的最大整数为:7424613。

输入格式

  • 第一行,一个正整数 n。第二行,n 个正整数。

输出格式

  • 一个正整数,表示最大的整数。
Sample Input
  • 3
    13 312 343
Sample Output
  • 34331213

题解

  • 这道题目中使用string类来表示字符串比较方便(可以使用“+”将两个string对象合并起来)

  • 另外,这道题中还涉及到了sort中cmp的用法,由于最终要得到是最大整数,因此使用cmp将n组字符串按照拼接之后从大到小的方式排序。

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string str[25];
bool cmp(string a,string b){
	return a+b>b+a;//字符串a,b两种不同的拼接方式进行比较,将当a+b较大时返回1,此时将a排在b的前面。
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
	cin>>str[i];
	}
	sort(str,str+n,cmp);
	for(int j=0;j<n;j++){
		cout<<str[j];
	}
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值