zoukankan      html  css  js  c++  java
  • [洛谷P1092][题解]虫食算

    我不是题目

    1.暴力枚举全排列,30分,代码不放了

    2.思考如何剪枝

    剪枝一:由于是竖式加法,所以可以枚举已经知道的部分,如果矛盾就退出

    例:

    xx1xx

    xx1xx

    -------

    xx4xx

    显然是错的

    剪枝二:如果按字母顺序枚举大概率有数没有枚举过,太分散

    考虑从后往前枚举,碰到哪个先枚举哪个

    至此,已100分。

    Code:

     1 #include<bits/stdc++.h>
     2 #define rint register int
     3 #define debug cout<<"AJH AK IOI!!!"<<endl
     4 using namespace std;
     5 
     6 int n,tr[100];
     7 string a,b,s;
     8 bool vis[30];
     9 int pmt[30],cnt,used[30];
    10 
    11 inline int id(char a){return a-'A'+1;}
    12 inline char ch(int a){return a+'A'-1;}
    13 
    14 inline void Check(){
    15     int cr=0;
    16     for(rint i=n-1;i>=0;i--){
    17         int sum=tr[a[i]]+tr[b[i]]+cr;
    18         //检验答案 
    19         if(sum%n!=tr[s[i]])return;
    20         cr=sum/n;
    21     }
    22     cout<<tr['A'];
    23     for(rint i='A'+1;i<='A'+n-1;i++)cout<<" "<<tr[i];
    24     cout<<endl;
    25     exit(0);
    26 }
    27 
    28 inline bool Prune(){
    29     for(int i=n-1;i>=0;i--){
    30         //有没搜过的就跳 
    31         int ta=tr[a[i]],tb=tr[b[i]],ts=tr[s[i]];
    32         if(ta==-1||tb==-1||ts==-1)continue;
    33         //剪枝一:如果答案错误就返回0 
    34         if((ta+tb)%n!=ts){
    35             if((ta+tb+1)%n!=ts)return 0;
    36         }
    37     }
    38     return 1;
    39 }
    40 
    41 void DFS(int now){
    42     if(now>n){
    43         Check();
    44         return;
    45     }
    46     //开始深搜啦~ 
    47     for(rint i=n-1;i>=0;i--){
    48         if(vis[i])continue;
    49         tr[ch(pmt[now])]=i;//调整排列 
    50         if(Prune()){
    51             vis[i]=1;
    52             DFS(now+1);
    53             vis[i]=0;
    54         }
    55     }
    56     tr[ch(pmt[now])]=-1;//别忘了标回去 
    57 }
    58 
    59 int main(){
    60     cin>>n>>a>>b>>s;
    61     memset(tr,-1,sizeof(tr));
    62     //剪枝二:调整搜索顺序 
    63     for(rint i=n-1;i>=0;i--){
    64         rint ai=id(a[i]);
    65         rint bi=id(b[i]);
    66         rint si=id(s[i]);
    67         //先搜后面的 
    68         if(!used[ai])pmt[++cnt]=ai,used[ai]=1;
    69         if(!used[bi])pmt[++cnt]=bi,used[bi]=1;
    70         if(!used[si])pmt[++cnt]=si,used[si]=1;
    71     }
    72     
    73     DFS(1);
    74     return 0;//功德圆满 
    75 }
    内容来自_ajhfff_的博客(https://www.cnblogs.com/juruoajh/),未经允许,不得转载。
  • 相关阅读:
    VMware安装Centos7超详细过程
    Linux部署Web项目
    Entity Framework快速入门IQueryable与IEnumberable的区别
    ASP.NET MVC3中的路由系统(Routes)
    C# Lambda表达式概述
    WCF大数据量传输解决要点
    div滚动条样式设计
    ASP.NET MVC 自定义路由
    C# Lambda表达式学习笔记
    C# 操作excel
  • 原文地址:https://www.cnblogs.com/juruoajh/p/12104141.html
Copyright © 2011-2022 走看看