您的位置:首页 > 其它

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

2016-05-06 13:13 232 查看
最近在刷搜索套餐

我先做了一道简单的

虫食算。。。。

我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
;
int a
,b
,c
,t
,n;
bool jinwei
;
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");
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索 剪枝 NOIP