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

最近在刷搜索套餐
我先做了一道简单的
虫食算。。。。
我GO die了。。。。。。。。。。。
这都是啥啊!!!!!!!!!!!!!!!

[NOIP2004]虫食算 T4 简单搜索+剪枝_第1张图片

总之就是一个搜啊。。。。
从最右面开始搜
每一行行尾进行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");
}

[NOIP2004]虫食算 T4 简单搜索+剪枝_第2张图片

你可能感兴趣的:(搜索,剪枝,noip)