您的位置:首页 > 其它

[搜索顺序] POJ 1165 [IOI 1994] The Primes

2016-12-12 14:40 232 查看
论文:王知昆--搜索顺序的选择

根据元素取值范围和制约力确定搜索顺序

1、最后一行和最后一列是取值范围最小的搜索元素,而且它们对其他所有的元素都有一定的制约力,因此要放在搜索序列的最前面。

2、两条对角线同样影响到其他所有的搜索元素,制约力在剩下的格子中是最大的,因此也应当优先搜索。

3、剩下的行列依据它们取值范围的大小确定搜索顺序。

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;

const int lstx[]={
1,2,3,4,5,5,5,5,5,2,3,4,2,4,4,4,1,3,3,3,1,2,1,2
};
const int lsty[]={
5,5,5,5,5,1,2,3,4,2,3,4,4,2,1,3,4,4,2,1,2,3,3,1
};
const int tag[]={
0,0,0,0,1,0,0,0,2,0,0,4,0,3,0,2,0,1,0,2,1,0,1,2
};

struct Ans{
int a[6];
bool operator < (const Ans &B) const {
for (int i=1;i<=5;i++){
if (a[i]<B.a[i]) return 1;
if (a[i]>B.a[i]) return 0;
}
return 0;
}
}ans[10005];
int tot;

const int maxn=100000;

int vst[maxn+5],prime[maxn+5],num;

inline void Pre(){
for (int i=2;i<maxn;i++){
if (!vst[i]) prime[++num]=i;
for (int j=1;j<=num && (long long)prime[j]*i<maxn;j++){
vst[prime[j]*i]=1;
if (i%prime[j]==0) break;
}
}
}

int s,a[10][10];

inline bool check(int x,int y){
if (x==1||y==1) if (!a[x][y]) return 0;
int flag,tem,sum;
flag=0,tem=0,sum=0;
for (int j=1;j<=5 && !flag;j++)
if (a[x][j]!=-1) tem=tem*10+a[x][j],sum+=a[x][j]; else flag=1;
if (!flag)
if (vst[tem] || sum!=s)
return 0;
flag=0,tem=0,sum=0;
for (int i=1;i<=5 && !flag;i++)
if (a[i][y]!=-1) tem=tem*10+a[i][y],sum+=a[i][y]; else flag=1;
if (!flag)
if (vst[tem] || sum!=s)
return 0;
if (x==y){
flag=0,tem=0,sum=0;
for (int i=1;i<=5 && !flag;i++)
if (a[i][i]!=-1) tem=tem*10+a[i][i],sum+=a[i][i]; else flag=1;
if (!flag)
if (vst[tem] || sum!=s)
return 0;
}
if (x+y==6){
flag=0,tem=0,sum=0;
for (int i=5;i && !flag;i--)
if (a[i][6-i]!=-1) tem=tem*10+a[i][6-i],sum+=a[i][6-i]; else flag=1;
if (!flag)
if (vst[tem] || sum!=s)
return 0;
}
return 1;
}

void dfs(int t){
if (t==24){
++tot;
for (int i=1;i<=5;i++){
int tem=0;
for (int j=1;j<=5;j++)
tem=tem*10+a[i][j];
ans[tot].a[i]=tem;
}
return;
}
int x=lstx[t],y=lsty[t];
int sum=0;
if (tag[t]==1){
sum=0;
for (int i=1;i<=5;i++) if (a[i][y]!=-1) sum+=a[i][y];
a[x][y]=s-sum;
if (a[x][y]>=0 && a[x][y]<=9 && check(x,y))
dfs(t+1);
a[x][y]=-1;
}else if (tag[t]==2){
sum=0;
for (int j=1;j<=5;j++) if (a[x][j]!=-1) sum+=a[x][j];
a[x][y]=s-sum;
if (a[x][y]>=0 && a[x][y]<=9 && check(x,y))
dfs(t+1);
a[x][y]=-1;
}else if (tag[t]==3){
sum=0;
for (int i=1;i<=5;i++) if (a[i][6-i]!=-1) sum+=a[i][6-i];
a[x][y]=s-sum;
if (a[x][y]>=0 && a[x][y]<=9 && check(x,y))
dfs(t+1);
a[x][y]=-1;
}else if (tag[t]==4){
sum=0;
for (int i=1;i<=5;i++) if (a[i][i]!=-1) sum+=a[i][i];
a[x][y]=s-sum;
if (a[x][y]>=0 && a[x][y]<=9 && check(x,y))
dfs(t+1);
a[x][y]=-1;
}else{
for (int i=(x==1||y==1||x==5||y==5)?1:0;i<=9;i+=(x==5||y==5)?2:1){
a[x][y]=i;
if (check(x,y))
dfs(t+1);
a[x][y]=-1;
}
}
}

int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
Pre();
memset(a,-1,sizeof(a));
scanf("%d%d",&s,&a[1][1]);
dfs(0);
sort(ans+1,ans+tot+1);
for (int i=1;i<=tot;i++,putchar('\n'))
for (int j=1;j<=5;j++)
printf("%d\n",ans[i].a[j]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: