Luogu : P1966 경기 라인업 (증가 + / 지방 선거-, 분할 및 정복)

이야기:

여기에 사진 설명 삽입

분석 : 처음에는 아이디어가 없었습니다. 병합 및 정렬을위한 문제 솔루션을 살펴보십시오. 그러니 스스로 생각해보십시오.

하나를 주문하면 다른 하나도 주문되어 최소값을 얻습니다.

그런 다음 문제는 최소 교환 횟수 이후에 주문되는 일련의 숫자로 변환됩니다.

오랜만에 생각 해보니 예상하지 못해서 꼼꼼히 살펴 보았다.

이웃들이 이사하기 전에 실종 된 것으로 밝혀졌습니다. (이 질문은 leetcode에서 수행되어야한다는 것을 깨달았고 이동할 인접한 질문을 보지 못했습니다)

분명합니다. 좌우의 움직임이 정돈되면 불필요할까요?

지각 지식은 그렇지 않습니다.

강조 : 전진하는 것을 고려하거나 후진하는 것만 고려하면됩니다. ! ! ! ! (이유의 본질로 표시)

그것에 대해 생각할 가치가 있습니다!

따라서 전진 만 고려하면 후반부에는 전진 만 있어야한다. 그리고 포인터가 마지막 요소를 가리 키지 않는 경우 즉, 두 부분에 배치 할 요소가 있습니다.

암호:? ? 상태가 좋지 않습니다. 당분간 놓아 두십시오.

여기에 사진 설명 삽입

#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