zoukankan      html  css  js  c++  java
  • 2021 CCPC桂林站 D Assumption is All You Need (贪心)

    D. Assumption is All You Need

    • 题意:给你两个长度为\(n\)的数组\(A\)\(B\),每次可以交换\(A\)中的逆序对,问你\(A\)能否通过操作得到\(B\)

    • 题解:从后往前遍历,贪心策略是,越大的数在越前面越好,首先\(A_i\)一定不大于\(B_i\),不然gg,先确定\(B_i\)\(A\)中的位置\(p\),我们要交换\((a_p,a_i)\),但不能直接交换,否则\([p+1,i-1]\)这些位置上的数如果有大于\(a_i\)的,在交换之后就不能在移动到\(p\)这个位置了,这和我们的贪心策略相违背,所以我们在这个过程中需要不断地将最大的\(a_j(a_i<a_j<b_i,j\in[p+1,i-1])\)往前移,可以用后缀记录最大值,然后push进答案即可,具体的看代码应该就能理解了.

    • 题解

      #include <bits/stdc++.h>
      using namespace std;
      #define PII pair<int,int>
      #define fi first
      #define se second
      #define pb push_back
      #define ll long long
      #define ull unsigned long long
      #define PLL pair<ll,ll>
      const int N=10000010;
      const int mod=1e9+7;
      const int INF=0x3f3f3f3f;
      
      int n;
      int pos[N],a[N],b[N];
      int suf_mx[N];
      vector<PII> ans;
      
      int main(){
          int _;
          scanf("%d",&_);
          while(_--){
              scanf("%d",&n);
              ans.clear();
              for(int i=1;i<=n;++i) scanf("%d",&a[i]),pos[a[i]]=i;
              for(int i=1;i<=n;++i) scanf("%d",&b[i]);
              bool flag=true;
              for(int i=n;i>=1;--i){
                  if(a[i]==b[i]) continue;
                  if(a[i]>b[i]){
                      flag=false;
                      break;
                  }
                  int p=pos[b[i]];
                  for(int j=1;j<=n+1;++j) suf_mx[j]=0; 
                  suf_mx[i]=i;
                  for(int j=i-1;j>=p;--j){
                      if(a[j]<b[i]){
                          if(a[j]>a[suf_mx[j+1]]) suf_mx[j]=j;
                          else suf_mx[j]=suf_mx[j+1];
                      }
                      else suf_mx[j]=suf_mx[j+1];
                  }
                  while(p<i){
                      int x=p,y=suf_mx[p+1];
                      ans.pb({x,y});
                      swap(a[x],a[y]);
                      pos[a[x]]=x;
                      pos[a[y]]=y;
                      p=suf_mx[p+1];
                  }
              }
              if(!flag) puts("-1");
              else{
                  printf("%d\n",(int)ans.size());
                  for(auto w:ans) printf("%d %d\n",w.fi,w.se);
              }
          }
          return 0;
      }
      
      
       
      
  • 相关阅读:
    selenium+phantomjs爬取bilibili
    使用 python 开发 Web Service
    OBIEE 立方刷新的问题
    解析OracleOLAP使用MView刷新Cube
    Codeforces Round #755 (Div. 2, based on Technocup 2022 Elimination Round 2)(CF1589)题解
    Codeforces Round #754 (Div. 2)(CF1605)题解
    完美解读Linux中文件系统的目录结构
    C#中获取程序当前路径的集中方法
    30个优秀.net在线学习资源站点
    如何删除windows service(转帖)
  • 原文地址:https://www.cnblogs.com/lr599909928/p/15560159.html
Copyright © 2011-2022 走看看