Processing math: 100%

ARC082 D : Derangement(400)

作成日:2017.09.03
最終更新日:2017.09.03

問題概要

問題本文

 1,2,...,Nの順列p1,p2,...pNが与えられる。 操作「順列で隣り合う二つの数を選んで入れ替える」を0回以上行うことで、すべてのiにおいてpiiとなるようにする。 必要な操作の最小回数を求めよ。
制約
2N105
数列{pi}1,2,...,Nの順列

考え方

 pi=iである時はpi1あるいはpi+1と入れ替えなければならない。 この時pi1i,pi+1iであることから、piに対しては1回だけ操作を行えば良い。 また、それによって新たに操作を行わなければならない要素は生じない。 よってpi=iとなるiの個数だけ操作を行えば良い。 但しpi=iかつpi+1=i+1の時はこの2つの要素を選んで操作を行うことで操作の回数を1回減らすことができる。 以上より、先頭から要素を見ていきpi=iとなるものが現れたらpi+1と操作を行うことを繰り返せば良いことが分かる。

ソースコード

マクロ等はこちら

  1. const int MC = 100010;
  2. int N;
  3. int p[MC];
  4.  
  5. int main(){
  6. scanf("%d" , &N);
  7. repp(i,1,N+1){
  8. scanf("%d" , p + i);
  9. }
  10. int ans = 0;
  11. repp(i,1,N+1){
  12. if(p[i] == i){
  13. ++ans;
  14. ++i;
  15. }
  16. }
  17. printf("%d\n" , ans);
  18. return 0;
  19. }

解法まとめ

 先頭から要素を見ていきpi=iとなるものが現れたらpi+1と操作を行う。(10-17行)

ARC082の他の問題 C E F

自己紹介

プログラミングとか合成音声とか
詳しくはこちら
twitter

プライバシーポリシー

個人情報利用についてはこちら

最終更新日:2023.03.05

お問い合わせ

このページに関するお問い合わせはこちら

競技プログラミングMENU

問題を解くまでの道のり

その他

全体MENU

寄付モドキ

0冂から10000冂まで
詳しくはこちら