Processing math: 6%

2015年6月8日 星期一

[CF 549G] Happy Line

作法:

這題只要觀察到:當a_ia_{i+1}交換時,所有數形成的i+a_i的集合都不會變,因為當交換時這兩數的i+a_i值是從(i+a_i,i+1+a_{i+1})變成((a_{i+1}+1)+i,(a_i-1)+i+1) 。並且顯然這是充要的,也就是如果兩數列的i+a_i集合相同,那麼就可以把一個變成另一個(只要一個一個放到對的位子就好了)。所以現在有了i+a_i的集合,我們想要讓a_1,...,a_n是遞增的,那麼a_1的值越小越好,那麼就取i+a_i集合裡最小的那個數扣掉1就是所求的a_1了,這樣取會是最好的。同理a_2會取集合裡第二小的數,以此類推。因此只要按照i+a_i值排序就可以找出解了。

code :



#include<bits/stdc++.h>
using namespace std;
const int maxn=200000+10 ;
 
int a[maxn],ans[maxn] ;
main()
{
    int n ; scanf("%d",&n) ;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]) , a[i]+=i ;
    sort(a+1,a+n+1) ;
    for(int i=1;i<=n;i++)
    {
        ans[i]=a[i]-i ;
        if(i>1 && ans[i]<ans[i-1]){printf(":(\n") ; return 0 ;}
    }
    for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?'\n':' ') ;
}
 

沒有留言:

張貼留言