• 相等序列


    题目链接:https://www.nowcoder.com/questionTerminal/7492dceb022a4bbebb990695c107823e

    题目描述

    题目给定a1,a2...an,这样一个长度为n的序列,现在你可以给其中一些元素加上一个值x(只能加一次),然后可以给另外一些值减上一个值x(只能减一次),剩下的元素不能再进行操作。问最后有没有可能找到一个值x使所有元素的值相等。

    输入描述:

    输入第一行为一个整数k,代表有k个序列(k<100),接下来有2*k行:
    偶数行为一个整数n,代表给定序列的长度(1<=n<=100,000)
    奇数行包含n个元素,a1,a2...an,代表序列中的元素(0<=ai<=100,000)
     

    输出描述:

    输出k行,每行一个YES或者NO
    示例1

    输入

    1
    5
    1 3 3 2 1

    输出

    YES

    AC代码:
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int k;
        cin>>k;
        while(k--)
        {
            int n;
            int x;
            cin>>n;
            set<int> s;
            for(int i=0;i<n;i++)
            {
                cin>>x;
                s.insert(x);
            }
            set<int>::iterator it=s.begin();
            string ans;
            if(s.size()<3) ans="YES";
            else if(s.size()==3)
            {
                if((*s.begin()+*s.rbegin())/2==*(++it)) ans="YES";
                else ans="NO";
            }
            else ans="NO";
            cout<<ans<<endl;
        }
    }
    更加完善的AC_codes:
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
    	int k;
    	cin>>k;
    	while(k--)
    	{
    		int n;
    		int x;
    		cin>>n;
    		set<int> s;
    		for(int i=0;i<n;i++)
    		{
    			cin>>x;
    			s.insert(x);
    		}
    		set<int>::iterator it=s.begin();
    		string ans;
    		if(s.size()<3) ans="YES";
    		else if(s.size()==3)
    		{
    			if((*s.begin()+*s.rbegin())==2*(*(++it))) ans="YES";
    			else ans="NO";
    		}
    		else ans="NO";
    		cout<<ans<<endl;
    	}
    }
    
    
    

      



    参考大佬的相关思路:
    链接:https://www.nowcoder.com/questionTerminal/7492dceb022a4bbebb990695c107823e
    来源:牛客网

    序列的某些元素要同时增,减x之后 能够保持所有元素值一样,直接整个遍历计算是不现实的。
    
    
    我们知道,每次增,减的值应当是固定的,也就是x,那就说明比如:不能拿大的减1,小的加2这种形式,要么大的都减2,小的都加2;要么大的都减1,小的都加1。那要保证某两部分,一部分加x,一部分减x,最后要达到相等,那必然存在一个中介,这个中介是不能动的。就比如1 2 3这个序列,2是不能动的,1,3做减,加操作后,要和2相等,这就是我们所熟知的等差序列性质。那推广一下,1,2和3都可能都多个,比如1 1 1 2 2 2 3 3 3这种,但是唯一不变的就是数的类型只能有3种,不能说1 2 3 4这样子,那就不可能达到相等,因为上面分析过了,只能有1个中介。
    
    
    思考到这里,就基本可以确定思路了:我们不需要拿出所有的数(1 1 1 2 2 2 3 3 3),而只需要取出一个样本(1 2 3),同时样本数不能超过3个(1 2 3 4是不可以的),然后拿这3个样本来进行等差数列的分析(a[0] + a[2] = 2*a[1]),满足的话ans = “YES”,否则ans = "NO"。当然,不要忘了样本可能只有1个或者2个,那必然ans = "YES"。
    
    
    而要样本数只拿出一个,当然用的就是set容器了,利用它的去重和排序,我们可以省去大笔功夫,直接进行等差序列判断
    链接:https://www.nowcoder.com/questionTerminal/7492dceb022a4bbebb990695c107823e
    来源:牛客网
    
    #include <iostream>
    #include <set>
    #include <string>
    using namespace std;
     
    int main(){
        int k;  //k个序列
        cin >> k;
        while(k--){
            int n;  //序列长度
            int num; //元素值
            cin >> n;
            set<int> res;  //存储每一行的元素,但是每种类型只能存1个,并且会排序
            for(int i = 0; i < n; ++i){
                cin>>num;
                res.insert(num);
            }
            set<int>::iterator it = res.begin();
            string ans;
            if(res.size() < 3){ 
                ans = "YES";
            }
            else if(res.size() == 3){
                //只能一增一减,又因为是有序的,所以第一个增,第三个减,第二个不变。
                //比如1 5 8 就是不可以的,1 5 9就是可以的,利用等差序列性质
                //注意这里不能用res.end,因为end是指向最后一个元素的下一个位置
                if((*res.begin() + *res.rbegin())/2 == *(++it)){
                    ans = "YES";
                }
                else{
                    ans = "NO";
                }
            }
            else{
                ans = "NO";
            }
            cout << ans << endl;
        }
        return 0;
    }
    其他关于等差数列的小trick:
    https://www.cnblogs.com/mtcnn/p/9423846.html
    https://blog.csdn.net/qq_24489717/article/details/50350449
     
     
  • 相关阅读:
    javascript实现非递归--归并排序
    javascript实现二分查找
    深入javascript作用域链到闭包
    c++学习笔记2--constexpr,类型别名,auto
    用 Numba 加速 Python 代码
    Django1和2的区别
    Git的使用
    文件锁fcntl
    Https原理
    Flask-Login
  • 原文地址:https://www.cnblogs.com/dragondragon/p/13418251.html
Copyright © 2020-2023  润新知