码迷,mamicode.com
首页 > 其他好文 > 详细

P1092 虫食算[搜索]

时间:2019-11-14 21:42:21      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:直接   class   优化   部分   mod   char   getch   line   space   

这个式子是是由\(A\sim A+N\)组成的,那么\(A\sim A+N\)就只能等于\(0\sim N-1\),因此我们每次对\(A\sim A+N\)的取值做一个新的排列,然后judge一下当前状态是否可行,若可行直接输出解。

显然\(N!\)过于庞大,需要剪枝。

剪枝:

假设一个这种情况:

XXXAXXX
XXXBXXX
XXXCXXX

其一,在一个排列中设\(A+B=k\)\(A+B<C\)时,在其它任意一个排列中,若\(A+B<k\),那么这个排列肯定不合法,\(A+B<C+N\)同理。

其二,在一排里,进位至多为1,那么仅\((A+B)\%N=C\)\((A+B+1)\%N=C\)这两种情况成立。有了这个优化我们就不需要一了。

其三,由于三排长度都是\(N\),意味着最高位没有进位。

其四,在二的判断中,倘若我们能够早一些找到不合法的情况,那么这个题就可以得到更好的优化。显然,在检验二时,我们是从某一边的最边上那一排开始扫到末尾那一排,所有如果我们搜索时先搜出早一点扫到的那部分字母对应的数字,就会减少大量无用枝条。

复杂度\(O(EIS)\)

参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 101
#define MOD 2520
#define E 1e-12
using namespace std;
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,num[N],q[N],cnt;
char mp[4][N];
bool v[N],use[N];
inline void judge()
{
    int add=0;
    for(int i=n;i>=1;--i){
        if((num[mp[1][i]]+num[mp[2][i]]+add)%n==num[mp[3][i]])
            add=(num[mp[1][i]]+num[mp[2][i]]+add)/n;
        else return;
    }
    for(int i='A';i<'A'+n;++i)
        printf("%d ",num[i]);
    exit(0);
}
inline bool can()
{
    for(int i=n;i>=1;--i){
        if(num[mp[1][i]]==-1||num[mp[2][i]]==-1||num[mp[3][i]]==-1) continue;
        if((num[mp[1][i]]+num[mp[2][i]])%n!=num[mp[3][i]])
            if((num[mp[1][i]]+num[mp[2][i]]+1)%n!=num[mp[3][i]])
                return 0;
    }
    return 1;
}
inline void dfs(int now)
{
    if(now>n){
        judge();return;
    }
    for(int i=n-1;i>=0;--i){
        if(use[i]) continue;
        num[q[now]+'A']=i;
        if(can()){
            use[i]=1;
            dfs(now+1);
            use[i]=0;
        }
    }
    num[q[now]+'A']=-1;
}
int main()
{
    n=read();
    memset(num,-1,sizeof(num));
    for(int i=1;i<=3;++i) scanf("%s",mp[i]+1);
    for(int i=n;i>=1;--i){
        if(!v[mp[1][i]-'A']) q[++cnt]=mp[1][i]-'A',v[mp[1][i]-'A']=1;
        if(!v[mp[2][i]-'A']) q[++cnt]=mp[2][i]-'A',v[mp[2][i]-'A']=1;
        if(!v[mp[3][i]-'A']) q[++cnt]=mp[3][i]-'A',v[mp[3][i]-'A']=1;
    }
    dfs(1);
    return 0;
}

P1092 虫食算[搜索]

标签:直接   class   优化   部分   mod   char   getch   line   space   

原文地址:https://www.cnblogs.com/DarkValkyrie/p/11862659.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!