2 条题解

  • 0
    @ 2025-10-8 17:03:43

    B29 IDA*算法 Booksort

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N=16;
    int n,dep;
    int a[N],b[5][N]; //b是a的每层备份
    
    int f(){ //估价函数: 修正错误连接的次数⌈tot/3⌉
      int tot=0;  
      for(int i=0; i<n-1; i++) 
        if(a[i+1]!=a[i]+1) tot++; //错误连接数
      return (tot+2)/3; //每次最多修正3个错误连接  
    }
    bool check(){ //检查正确顺序
      for(int i=0; i<n; i++)
        if(a[i]!=i+1) return false; //检查正确顺序
      return true; //检查正确顺序
    }
    bool dfs(int u){
      if(u+f() > dep) return false; //越界
      if(check()) return true; //成功
      for(int i=0; i<n; i++)
        for(int j=i+1; j<n; j++)
          for(int k=j,x,y; k<n; k++){
            memcpy(b[u],a,sizeof a); //备份
            for(x=j,y=i; x<=k; x++,y++) 
              a[y]=b[u][x]; //[j,k]前插至i
            for(x=i; x<=j-1; x++,y++) 
              a[y]=b[u][x]; //[i,j-1]后移
            if(dfs(u+1)) return true;
            memcpy(a,b[u],sizeof a); //恢复现场
          }
      return false;
    }
    int main(){
      int T; cin>>T;
      while(T--){
        cin>>n;
        for(int i=0; i<n; i++) cin>>a[i];
        for(dep=0; dep<5&&!dfs(0); dep++);
        if(dep>=5) puts("5 or more");
        else printf("%d\n",dep);
      }
    }
    
    • 0
      @ 2025-10-8 17:03:29

      B29 IDA*算法 Booksort

      #include <cstdio>
      #include <cstring>
      #include <iostream>
      #include <algorithm>
      using namespace std;
      
      const int N=16;
      int n,dep;
      int a[N],b[5][N]; //b是a的每层备份
      
      int f(){ //估价函数: 修正错误连接的次数⌈tot/3⌉
        int tot=0;  
        for(int i=0; i<n-1; i++) 
          if(a[i+1]!=a[i]+1) tot++; //错误连接数
        return (tot+2)/3; //每次最多修正3个错误连接  
      }
      bool check(){ //检查正确顺序
        for(int i=0; i<n; i++)
          if(a[i]!=i+1) return False;
        return True;
      }
      bool dfs(int u){
        if(u+f()>dep) return False; //越界
        if(check()) return True; //成功
        for(int i=0; i<n; i++)
          for(int j=i+1; j<n; j++)
            for(int k=j,x,y; k<n; k++){
              memcpy(b[u],a,sizeof a); //备份
              for(x=j,y=i; x<=k; x++,y++) 
                a[y]=b[u][x]; //[j,k]前插至i
              for(x=i; x<=j-1; x++,y++) 
                a[y]=b[u][x]; //[i,j-1]后移
              if(dfs(u+1)) return True;
              memcpy(a,b[u],sizeof a); //恢复现场
            }
        return False;
      }
      int main(){
        int T; cin>>T;
        while(T--){
          cin>>n;
          for(int i=0; i<n; i++) cin>>a[i];
          for(dep=0; dep<5&&!dfs(0); dep++);
          if(dep>=5) puts("5 or more");
          else printf("%d\n",dep);
        }
      }
      • 1

      信息

      ID
      2985
      时间
      1000ms
      内存
      512MiB
      难度
      8
      标签
      递交数
      30
      已通过
      5
      上传者