[NOIP2004]虫食算 T4 简单搜索+剪枝

最近在刷搜索套餐

我先做了一道简单的

虫食算。。。。

我GO die了。。。。。。。。。。。

这都是啥啊!!!!!!!!!!!!!!!

总之就是一个搜啊。。。。

从最右面开始搜

每一行行尾进行check

基本上能过9个点。。。。。。。。

剪枝的话 ,考虑检索前面的每一行 如果改行的数字都己经试过,那么就可以判断合法性,如果已经有两个试过的话,考虑第三个数是否可能(可能已经被用过)

注意:试数的时候从后向前试。。。坑爹的数据

注意进位即可

下面是代码,调试信息懒得删。。。。搜索的第四层可删 略长。。。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <algorithm>
#define N 100
using namespace std;
char str[N];
int a[N],b[N],c[N],t[N],n;
bool jinwei[N];
int calc(int ROW)
{return t[a[ROW]]+t[b[ROW]];}
inline void solve()
{
    for(int i=0;i<n-1;++i)cout<<t[i]<<" ";
    cout<<t[n-1];
    puts("");
}
inline int pre(int ROW)
{
    int times=0;
    if(t[a[ROW]]!=-1)++times;
    if(t[b[ROW]]!=-1)++times;
    if(t[c[ROW]]!=-1)++times;
    return times;
}
/*int Call_check(int ROW,int exist)
{
    for(int i=ROW;i>=1;--i)
    {
        int k=pre(i);
    /*  printf("CHECK at LINE ");printf("%d\n",__LINE__);
        printf("ROW==%d EXIST==%d\n",ROW,exist);*/
/*      if(k==3)
        {
            int x=calc(i);
            if(x%n==t[c[ROW]]||(x+1)%n==t[c[ROW]])continue;
            else return false;
        }
        else if(k==2)
        {
            if(t[c[ROW]]==-1)
            {
                int x=calc(i);
                /*printf("CHECK at LINE ");printf("%d\n",__LINE__);
                puts("solve !");
                solve();
                printf("ROW=%d,a[ROW]=%d,b[ROW]=%d,c[ROW]=%d\n",ROW,a[ROW],b[ROW],c[ROW]);*/
/*                int tmp1=x%n,tmp2=(x+1)%n;
                if((1<<tmp1)&exist && (1<<tmp2)&exist)return false;
            }
            else if(t[b[ROW]]==-1)
            {
                if(t[c[ROW]]<=t[a[ROW]])
                {
/*                      printf("CHECK at LINE ");printf("%d\n",__LINE__);
                      puts("solve !");
                      solve();
                      printf("ROW=%d,a[ROW]=%d,b[ROW]=%d,c[ROW]=%d\n",ROW,a[ROW],b[ROW],c[ROW]);*/
/*                      int tmp1=t[c[ROW]]+n;
                      tmp1-=t[a[ROW]];
                      if((1<<tmp1)&exist)return -1;
                }
                else
                {
/*                    printf("CHECK at LINE ");printf("%d\n",__LINE__);
                    puts("solve !");
                    solve();
                    printf("ROW=%d,a[ROW]=%d,b[ROW]=%d,c[ROW]=%d\n",ROW,a[ROW],b[ROW],c[ROW]);*/
/*                    int tmp1=t[c[ROW]]-t[a[ROW]];
                    int tmp2=t[c[ROW]]+n-t[a[ROW]];
                    tmp2%=n;
                    if((1<<tmp1)&exist&&(1<<tmp2)&exist)return -1;
                }
            }
            else if(t[a[ROW]]==-1)
            {
/*                printf("CHECK at LINE ");printf("%d\n",__LINE__);
                puts("solve !");
                solve();
                printf("ROW=%d,a[ROW]=%d,b[ROW]=%d,c[ROW]=%d\n",ROW,a[ROW],b[ROW],c[ROW]);*/
/*                if(t[c[ROW]]<=t[b[ROW]])
                {
                    int tmp1=t[c[ROW]]+n;
                    tmp1-=t[b[ROW]];
                    if((1<<tmp1)&exist)return -1;
                }
                else
                {
                    int tmp1=t[c[ROW]]-t[b[ROW]];
                    int tmp2=t[c[ROW]]+n-t[b[ROW]];
                    tmp2%=n;
                    if((1<<tmp1)&exist&&(1<<tmp2)&exist)return -1;
                }
            }
        }
        else
            continue;
    }
    return 1;
}*/
inline int Call_check(int ROW,int exist)
{
    for(int i=ROW;i>=1;--i)
    {
        int k=pre(i);
    /*  printf("CHECK at LINE ");printf("%d\n",__LINE__);
        printf("ROW==%d EXIST==%d\n",ROW,exist);*/
        if(k==3)
        {
            int x=calc(i);
            if( x%n==t[c[i]] || (x+1)%n==t[c[i]])continue;
            else return -1;
        }
    }
    return 1;
}
inline int recheck(int ROW)
{
    if(t[a[ROW]]!=-1&&t[b[ROW]]!=-1&&t[c[ROW]]!=-1)
    {
        int tmp=calc(ROW);
        if(jinwei[ROW])++tmp;
        int k=tmp;
        tmp%=n;
        if(tmp^t[c[ROW]])return -1;
        else if(k>=n)
        {
            jinwei[ROW-1]=true;
            return 2;
        }
        else
        {
            return 1;
        }
    }
    else
    {
        return 0;
    }
}
inline bool DFS(int LINE,int ROW,int exist)
{
/*  if(ROW==18)
    {
        printf("CHECK at LINE ");printf("%d\n",__LINE__);
        printf("LINE==%d ROW==%d EXIST==%d\n",LINE,ROW,exist);
        solve();
    }*/
    if(LINE==4)
    {
        int tmp=calc(ROW);
        //printf("%d\n",tmp );
        //*if(tmp<0)
        /*{
            printf("Check at LINE 23\n");
            printf("LINE=%d ROW=%d\n",LINE,ROW );
            for(int i=1;i<=n;++i)
                printf("%d ",t[a[i]] );
            puts("");
            for(int i=1;i<=n;++i)
                printf("%d ",t[b[i]] );
            puts("");
            for(int i=1;i<=n;++i)
                printf("%d ",t[c[i]] );
            puts("");
        }*/
        if(ROW==n)
        {
            if(tmp%n==t[c[ROW]])
            {
                if(tmp>=n) jinwei[ROW-1]=true;
                if( DFS(1,ROW-1,exist))return true;
                else { jinwei[ROW-1]=false;return false;}
            }
            else return false;
        }
        else
        {
            if(ROW==1)
            {
                int re=recheck(ROW);
                if(re==-1)return false;
                else if(re==2&&ROW!=1)
                {
                    if(DFS(1,ROW-1,exist))return true;
                    else
                    {
                        jinwei[ROW-1]=false;
                        return false;
                    }
                }
                else if(re==2&&ROW==1)
                {
                    solve();
                    return true;
                }
                else if(re==1&&ROW!=1)
                {
                    if(DFS(1,ROW-1,exist))
                    return true;
                    else return false;
                }
                else if(re==1&&ROW==1)
                {
                    solve();
                    return true;
                }
                else if(!re)
                {
                    if(jinwei[ROW])
                    {
                        if((tmp+1)%n==t[c[ROW]])
                        {solve();return true;}
                        else
                        {   return false;}
                    }
                    else
                    {
                        if(tmp%n==t[c[ROW]])
                        {
                            solve();return true;}
                        else
                            return false;
                    }
                }
            }
            else
            {
                if(jinwei[ROW])
                {
                    if((tmp+1)%n==t[c[ROW]])
                    {
                        if(tmp+1>=n)
                        {
                            jinwei[ROW-1]=true;
                            if(DFS(1,ROW-1,exist))return true;
                            jinwei[ROW-1]=false;return false;
                        }
                        else
                        {
                            return DFS(1,ROW-1,exist);
                        }
                    }
                }
                else
                {
                    if(tmp%n==t[c[ROW]])
                    {
                        if(tmp>=n)
                        {
                            jinwei[ROW-1]=true;
                            if( DFS(1,ROW-1,exist))return true;
                            jinwei[ROW-1]=false;return false;
                        }
                        else
                        {
                            if( DFS(1,ROW-1,exist))return true;
                            else return false;
                        }
                    }
                }
            }
        }
    }
    else
    {
        if(LINE==1)
        {
            int re=recheck(ROW);
            if(re==-1)return false;
            else if(re==2&&ROW!=1)
            {
                if(DFS(1,ROW-1,exist))return true;
                else
                {
                    jinwei[ROW-1]=false;
                    return false;
                }
            }
            else if(re==2&&ROW==1)
            {
                solve();
                return true;
            }
            else if(re==1&&ROW!=1)
            {
                if(DFS(1,ROW-1,exist))
                return true;
                else return false;
            }
            else if(re==1&&ROW==1)
            {
                solve();
                return true;
            }
            //printf("ROW==%d  t[a[ROW]]=%d  a[ROW]=%d\n",ROW,t[a[ROW]],a[ROW]);
            else if(re==0)
            {
                if(t[a[ROW]]!=-1) return DFS(LINE+1,ROW,exist);
                else
                {
                    for(int i=n-1;i>=0;--i)
                    {
                        if((1<<i)&exist)continue;
                        t[a[ROW]]=i;
                        int ss=Call_check(ROW,exist|(1<<i));
                        if(ss==-1){t[a[ROW]]=-1;continue;}
                        //cout<<t[a[ROW]]<<endl;
                        if(DFS(LINE+1,ROW,exist|(1<<i)))return true;
                        t[a[ROW]]=-1;
                    }
                    return false;
                }
            }
        }
        else if(LINE==2)
        {
            int re=recheck(ROW);
            if(re==-1)return false;
            else if(re==2&&ROW!=1)
            {
                if(DFS(1,ROW-1,exist))return true;
                else
                {
                    jinwei[ROW-1]=false;
                    return false;
                }
            }
            else if(re==2&&ROW==1)
            {
                solve();
                return true;
            }
            else if(re==1&&ROW!=1)
            {
                if(DFS(1,ROW-1,exist))
                return true;
                else return false;
            }
            else if(re==1&&ROW==1)
            {
                solve();
                return true;
            }
            else if(re==0)
            {
                if(t[b[ROW]]!=-1)return DFS(3,ROW,exist);
                else
                {
                    for(int i=n-1;i>=0;--i)
                    {
                        if((1<<i)&exist)continue;
                        t[b[ROW]]=i;
                        int x=Call_check(ROW,exist|(1<<i));
                        if(x==-1){t[b[ROW]]=-1;continue;}
                        if(DFS(LINE+1,ROW,exist|(1<<i)))return true;
                        t[b[ROW]]=-1;
                    }
                    return false;
                }
            }
        }
        else if(LINE==3&&ROW!=1)
        {
            //puts("Check at LINE 141");
            //printf("LINE = %d ROW = %d\n",LINE,ROW );
            //solve();
            int tmp=calc(ROW);
            if(jinwei[ROW])tmp++;
            int k=tmp%n;
            if(t[c[ROW]]!=-1&&k==t[c[ROW]])
            {
                if(tmp>=n)jinwei[ROW-1]=true;
                if( DFS(1,ROW-1,exist))return true;
                else
                {
                    jinwei[ROW-1]=false;return false;
                }
            }
            else if(t[c[ROW]]!=-1&&k!=t[c[ROW]])return false;
            else
            {
                if((1<<k)&exist)return false;
                else
                {
                    t[c[ROW]]=k;if(tmp>=n)jinwei[ROW-1]=true;
                    if(DFS(1,ROW-1,exist|(1<<k)))return true;
                    else{t[c[ROW]]=-1;jinwei[ROW-1]=false;return false;}
                }
            }
        }
        else if(ROW==1&&LINE==3)
        {
        //  puts("Check at LINE 168");
            int tmp=calc(1);if(jinwei[ROW])tmp++;tmp%=n;
            if(tmp==t[c[1]]){solve();return true;}
        }
    }
    return false;
}
int main()
{
    cin>>n;
    scanf("%s",str+1);for(int i=1;i<=n;++i)a[i]=str[i]-65;
    scanf("%s",str+1);for(int i=1;i<=n;++i)b[i]=str[i]-65;
    scanf("%s",str+1);for(int i=1;i<=n;++i)c[i]=str[i]-65;
//  for(int i=1;i<=n;++i)printf("%d",a[i] );puts("");
//  for(int i=1;i<=n;++i)printf("%d",b[i] );puts("");
//  for(int i=1;i<=n;++i)printf("%d",c[i] );puts("");
    for(int i=0;i<n;++i)t[i]=-1;    DFS(1,n,0);
    //if(cmp)   puts("23333333");
//  else
//  puts("wawawa");
}

时间: 2024-08-10 22:37:41

[NOIP2004]虫食算 T4 简单搜索+剪枝的相关文章

69. [NOIP2004] 虫食算

69. [NOIP2004] 虫食算 ★★★   输入文件:alpha.in   输出文件:alpha.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    + 8468#6633 ----------- 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是

NOIP2004 虫食算

四.虫食算 (alpha.pas/dpr/c/cpp) [问题描述] 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045     +    8468#6633        44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许

(DFS)noip2004——虫食算

1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 char a[4][28]; 5 bool vix[100],vi[28]; 6 int c[100],ge=1,an[100],t; 7 bool judge1() 8 { 9 char x,y,z; 10 for(int i=t;i>0;i--) 11 { 12 x=a[1][i];y=a[2][i];z=a[3][i]; 13 if

[Noip2004]虫食算 dfs

搜索问题的关键:优秀的搜索策略以及行之有效的减枝 对于这道题我们阶乘搜肯定不行所以我们按位搜,我们对每一位的三个数进行赋值,然后判解. 对于此一类的搜索乘上一个几十的常数来减枝往往要比直接搜要快得多,因为这样的问题他们都会有一个庞大的"之后",而且判断不存在较为容易,以我们多花一些时间进行减枝往往能达到剪掉许多枝的效果. 搜索还是看感觉,倒搜还是比正搜快...... #pragma GCC optimize("O3") #include <cstdio>

[NOIP2004] 提高组 洛谷P1092 虫食算

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

Luogu P1092 虫食算(枚举+剪枝)

P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 44445509678 其中 \(\#\) 号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是 \(5\) 和 \(3\) ,第二行的数字是 \(5\) . 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是 \(N\) 进制加法,算式中三个数都有 \(N\

noip 虫食算 (搜索)

描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子:43#9865#045+ 8468#6633= 44445506678其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制:首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字

【NOIP2004】虫食算

Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +   8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的

CODEVS1064虫食算noip提高组T4

题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    +    8468#6633       44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光