3 solutions

  • 1
    @ 2026-8-7 9:48:24
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    long long a[N],b[N];
    int n;
    int main(){
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr);
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	b[1]=a[1];
    	long long tmp1=0,tmp2=0;
    	//tmp1表示b2~bn中所有正数的和
    	//tmp2表示b2~bn中所有负数取绝对值之后的总和
    	for(int i=2;i<=n;i++){
    		b[i]=a[i]-a[i-1];
    		if(b[i]>0) tmp1=tmp1+b[i];
    		else tmp2=tmp2+abs(b[i]);
    	}
    	cout<<max(tmp1,tmp2)<<"\n";
    	cout<<abs(tmp1-tmp2)+1;
    	return 0;
    }
    
    • 1
      @ 2024-8-5 14:40:40

      包对的(没注释)

      #include<bits/stdc++.h>
      using namespace std;
      const int N=100010;
      int a[N],b[N];
      int main()
      {
      	int n;
      	cin>>n;
      	for(int i=1;i<=n;i++)
      	{
      		cin>>a[i];
      		b[i]=a[i]-a[i-1];
      	}
      	long long g=0,q=0;
      	for(int i=2;i<=n;i++)
      	{
      		if(b[i]>=0)
      		{
      			g+=b[i];
      		}
      		else
      		{
      			q-=b[i];
      		}
      	}
      	cout<<max(g,q)<<endl<<abs(g-q)+1;
      	return 0;
      }
      
      • 1
        @ 2024-4-24 10:28:07
        //对a上区间l - r上加减一个数
        //对差分数组为b[l] += 1 / -= 1
        //          b[r + 1] -= 1 / += 1
        
        //差分数组的定义
        //b[1] = a[1]
        //b[2] = a[2] - a[1]
        //b[3] = a[3] - a[2]
        //  ....
        //  ....
        //b[n] = a[n] - a[n - 1]
        
        //如果a数组的所有数相同
        //b[1] = a[1]
        //b[2] - b[n] 都=0
        
        //那么原问题就变成了
        //1.如果把一个差分数组b中b[2] - b[n]都变成0,且输出最少次数(最少,意味着可能贪心)
        //注意:此时b[1]可以是任意值,b[n + 1]也可以是任意值
        //2.在1的基础上,b[1]有多少种可能
        
        //对a的1-n区间内进行+1-1操作
        //可以映射为对b的1-n+1区间进行+1-1操作(只不过a数组是一个个+1-1,b数组是对l和r+1两个点进行+1-1)
        
        //可以分成下面四种情况(L表示a中的左端点,R表示a中的右端点)
        //1. 2 <= L <= R <= n - 1
        //此时对应到b数组的操作范围为2~n(因为b是对r+1进行操作,所以总比a的R多1)
        //那对应到差分操作,我们可以把b中2~n任意两个数进行+1-1,其中一个+1,另一个-1
        //2. L == 1,R <= n - 1
        //此时对应到b数组的操作范围为1~n
        //并且b[1] 要么+1要么-1, 另一个在2~n范围内的数也是要么+1要么-1
        //3. 2 <= L,R == n
        //此时对应到b数组的操作范围为2~n+1
        //并且b[n + 1] 要么+1要么-1,另一个在2~n范围内的数也是要么+1要么-1
        //4. L == 1,R == n
        //对应b数组中1~n+1范围,整体+1-1无意义
        
        //由于1情况可以同时把两个数一个+1一个-1
        //基于贪心思想,先使用操作1
        //操作1可以使用几次?
        //当b的2~n中如果不为0的数有大于0的也有小于0的,就可以用操作1
        //因此操作1最多可以用min(p, q)次,(p为b(2~n范围)中所有大于0的数之和,q为所有小于0的数之和)
        //剩下一些要么大于0要么小于0的数,可以用操作2或3,用的次数为abs(p - q)次
        //所有最少操作次数为min(p, q) + abs(p - q)次
        
        //问题二:b[1]有几种可能?
        //在操作2里b[1]会被+1-1
        //所有决定b[1]的值的操作为操作2
        //操作2可以用几次就有多少种取值(因为最后abs(p - q)次操作时,剩下的数要么正要么负,所有操作23的目的是把正数或负数-1或+1变成0,所有最后的操作23一定都是+1或都是-1)
        //最后有abs(p - q)次操作,操作2可以用0,1....abs(p - q)次
        //所有答案是abs(p - q) + 1
        
        
        #include<bits/stdc++.h>
        using namespace std;
        const int N=100010;
        int a[N],b[N];
        typedef long long LL;
        int main()
        {
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
            {
                cin>>a[i];
            }
            for(int i=1;i<=n;i++)
            {
                b[i]=a[i]-a[i-1];
            }
            LL p=0,q=0;
            for(int i=2;i<=n;i++)
            {
                if(b[i]>0)
                {
                    p+=b[i];
                }
                else 
                {
                    q-=b[i];
                }
            }
            cout<<max(p,q)<<endl;
            cout<<abs(p-q)+1<<endl;
            return 0;
        }
        
        • 1

        Information

        ID
        172
        Time
        1000ms
        Memory
        256MiB
        Difficulty
        6
        Tags
        # Submissions
        53
        Accepted
        18
        Uploaded By