Luogu:P1966の試合が並びます(+ /地方選挙の増加-分割統治)

トピック:

ここに画像の説明を挿入

分析:最初はアイデアがありませんでしたが、マージしてソートするための問題の解決策を見てください。自分で考えてみてください。

一方を注文すると、もう一方も注文され、最小値が取得されます。

次に、問題は一連の数値に変換され、最小交換回数の後に順序付けされます。

長い間考えていたのですが、期待していなかったので慎重に解決策を検討しました

彼らが動くことができる前に隣人が行方不明であることが発見されました。(私はこの質問がリートコードで行われるべきだったことに気付き、隣接する質問が移動するのを見ていませんでした)

はっきりしているのですが、左右の動きが整然としていれば無駄でしょうか?

知覚的な知識はありません。

強調する:前進することだけを考える必要があるか、後退することだけを考える必要がある、それだけです!(理由の本質としてマークされています)

それについて考える価値がある!

したがって、前進のみを考えると、後半は前進のみとなるはずです。そして、どちらのポインターも最後の要素を指していない場合、つまり、両方の部分に配置される要素があります。

コード:?状態は良くないので、とりあえず手放します。

ここに画像の説明を挿入

#include<bits/stdc++.h>
using namespace std;
#include<bits/stdc++.h>
using namespace std;
int m;
int B[100005];
int ans=0;
struct node{
    
    
 int x1;
 int x2;
} A[100005];
bool cmp(node n1,node n2)
{
    
    
 return n1.x2<n2.x2;
}
void f(int x,int y)
{
    
    //包括下标为x和下标为y的。   从小到大排序 
 if(x==y) return;
 if(x+1==y)
 {
    
    
  if(A[x].x1>A[y].x1) {
    
    
   ans++; swap(A[x].x1,A[y].x1);
   ans=ans%(100000000-3);
  }
  return;
 } 
 int c=(x+y)/2;
 f(x,c);
 f(c+1,y);
 //合并
 int b1=x,b2=c+1;//合并时的两个指针 
 int bb=x;
 while(1)
 {
    
    
  if(b1==c+1 && b2==y+1) break;
  if(b1==c+1)
  {
    
    
   B[bb]=A[b2].x1;bb++;b2++;
  }
  else if(b2==y+1)
  {
    
    
   B[bb]=A[b1].x1;bb++;b1++;
  }
  else{
    
    
   if(A[b1].x1>A[b2].x1) 
   {
    
    
    B[bb]=A[b2].x1;bb++;b2++;
    ans=ans+b2-bb;
    ans=ans%(100000000-3);
    }
   else{
    
    
    B[bb]=A[b1].x1;bb++;b1++;
   }
  }
 }
  for(int i=x;i<=y;i++)
  {
    
    
    A[i].x1=B[i];
 }
}
int main()
{
    
    
  cin>>m; 
  for(int i=0;i<m;i++) cin>>A[i].x1;
  for(int i=0;i<m;i++) cin>>A[i].x2;
  sort(A,A+m,cmp);
  /*for(int i=0;i<m;i++)
  {
   cout<<A[i].x1<<' '<<A[i].x2<<endl;
   } */
  f(0,m-1);
  cout<<ans;
}

おすすめ

転載: blog.csdn.net/weixin_42721412/article/details/108553343