[修补道路] 题解

一.题目

        题目描述

               小可家门口的路历经沧桑,已经不复平坦,变得坑坑洼洼的。

               于是小可拜托达达找了一个施工队来修补道路。施工队把这个道路分成了 n 段,然后测量了这 n 段各自的高度。

                施工队的人对小可说:“我们现在要通过两种方式按段修复这条道路:1 、对有些路段填充一些材料,增加 x 高度。 2 、对有些路段削减掉 x 的高度。当然有的路段我们可能什么都不做。”

                x 是一个固定值,小可并不知道具体是多少。但是小可想知道通过这种方式,有没有可能让这个道路重新变得平坦。

        输入描述

                第一行一个正整数 n (1≤ n≤ 105)

                第二行有 n 个整数 ai (0≤ a_i≤ 109),代表每段路的高度。

        输出描述

                如果可能重新变得平坦,输出"YES"。否则输出"NO"。平坦即为所有路段高度都相同。

        样例

                输入

                5 1 3 3 2 1

                输出

                YES

二.思路

        由于x并没有给出具体值,因此需要我们去构造。但这个题不是让我们找出x,而是问有没有方法。

        因此我们只需要去重,然后分类讨论判断就可以了。

        很容易想出用set

三.代码详解

        开set 

set<long long> se;

        在输入的过程中将数据插入进set

for(int i=1;i<=n;i++){
		cin>>t;//t是之前开好的 
		se.insert(t);
	}

        开始分类讨论。定义len=se.size();

        因为set自带去重特性,所以若len为1(无需修补)或len为2(选择一个加/减),一定可以修补。

if(len==1||len==2){
		printf("YES");
}

        若len为3,有两种情况。

                1. 三个数等差。此时x=公差。

                (例:去重后se里是1 3 5,x=3-1=5-3。)

                2. 三个数不等差。此时无解   

                (例:去重后se里是1 3 4,无论基准选哪个,x都有两个值。)

if(len==3){
	long long a[4],tot=1;
	for(set<ll>::iterator it=se.begin();it!=se.end();it++){
		a[tot++]=*it;
	}
	if(a[2]-a[1]==a[3]-a[2]){
		printf("YES");
	}
	else{
		printf("NO");
	}
}

        若len=4,一定无解。(x至少有两个值)

if(len==4){
	printf("NO");
}

四.AC代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,t;
set<ll>se;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>t;
		se.insert(t);
	}
	ll len=se.size();
	if(len==1||len==2){
		printf("YES");//若len为1(无需修补)或len为2(选择一个加/减),一定可以修补
	}
	else if(len==3){
		ll a[4],tot=1;
		for(set<ll>::iterator it=se.begin();it!=se.end();it++){
			a[tot++]=*it;
		}
		if(a[2]-a[1]==a[3]-a[2]){
			printf("YES");//此时x=公差,有解 
		}
		else{
			printf("NO");//否侧无解 
		}
	}
	else{
		printf("NO");//若len=4,一定无解
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值