AtCoder Non-decreasing(数学思维)

题目链接:https://abc081.contest.atcoder.jp/tasks/arc086_b

题目大意:有n个数,最多可以执行2*n次操作,每次可以选择将ai加到aj上,最终使得该序列满足a1<=a2<=a3....<=an。求操作过程,答案不唯一。

解题思路:我们分三种情况讨论:

     ①a1~an都大于等于0,那么只要从左往右使a2+=a1,a3+=a2,.....an+=an-1.总共n-1次操作就能保证a1<=a2<=a3....<=an.

     ②a1~an都小于等于0,那么只要从右往左使an-1+=an,.....a2+=a3,a1+=a2.总共n-1次操作就能保证a1<=a2<=a3....<=an.

     ③a1~an中有正数也有负数,取最小值MIN和最大值MAX,若abs(MAX)>=abs(MIN),就令a1~an都加上MAX,n次操作就可以得到情况①,总计2*n-1次操作。

     若abs(MAX)<abs(MIN),就令a1~an都加上MIN,n次操作就可以得到情况②,总计2*n-1次操作。

     总结一下,我们只要根据abs(MAX)和abs(MIN)的大小执行2*n-1次操作,就一定可以得到满足条件的序列。

代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<string>
13 #define INF 0x3f3f3f3f
14 #define LC(a) (a<<1)
15 #define RC(a) (a<<1|1)
16 #define MID(a,b) ((a+b)>>1)
17 #define fin(name)  freopen(name,"r",stdin)
18 #define fout(name) freopen(name,"w",stdout)
19 #define CLR(arr,val) memset(arr,val,sizeof(arr))
20 #define FOR(i,start,end) for(int i=start;i<=end;i++)  
21 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
22 using namespace std;
23 typedef long long LL;
24 const int N=1e3+5;
25 
26 int a[N];
27 
28 int main(){
29     int n,ma=1,mi=1;
30     scanf("%d",&n);
31     for(int i=1;i<=n;i++){
32         scanf("%d",&a[i]);
33         if(a[i]<a[mi]) 
34             mi=i;
35         if(a[i]>a[ma]) 
36             ma=i;
37     }
38     printf("%d
",2*n-1);
39     if(abs(a[ma])>=abs(a[mi])){
40         for(int i=1;i<=n;i++){
41             printf("%d %d
",ma,i);
42         }
43         for(int i=2;i<=n;i++){
44             printf("%d %d
",i-1,i);
45         }
46     }
47     else{
48         for(int i=1;i<=n;i++){
49             printf("%d %d
",mi,i);
50         }
51         for(int i=n-1;i>=1;i--){
52             printf("%d %d
",i+1,i);
53         }
54     }
55     return 0;
56 }
原文地址:https://www.cnblogs.com/fu3638/p/8028701.html