[搜索顺序] 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;
}
根据元素取值范围和制约力确定搜索顺序
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;
}
相关文章推荐
- POJ 2362(Square-搜索剪枝1-相对顺序)
- POJ 1166&IOI 1994 The blocks 暴力枚举 解题报告
- POJ 1579 DP顺序控制不容易使,改为记忆搜索 !!!
- !POJ 2488 dfs--按顺序搜索
- POJ-2488 A Knight's Journey(需注意搜索顺序的深搜)
- POJ 1165 The Primes 笔记
- POJ - 2362 - 搜索顺序和方法很重要..
- POJ 2488 A Knight's Journey (dfs+改变搜索顺序)
- 关于DLL搜索路径顺序的一个问题
- 关于DLL搜索路径顺序的一个问题
- poj 1775 简单搜索
- POJ 3414-Pots 简单搜索 BFS
- poj3189 二分搜索 + 二分图多重匹配
- 关于API的DLL的搜索顺序问题
- POJ 1011-Sticks 简单搜索DFS
- Windows下装入DLL的搜索顺序
- POJ_1426(搜索)
- POJ 3126-Prime Path 简单搜索 BFS
- DLL文件的搜索顺序
- POJ-1011-Sticks(经典搜索)