思路:dfs。搜索每一次平移几格。
剪枝:
1、如果当前走过的步数加上之后走过的最小的步数,大于等于当前找到的最小的结果,那么剪枝。
2、因为有些点一定不能走,所以提前找出可以走的点。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<sstream>
#include<queue>
#include<set>
using namespace std;
#define m 5
#define t 9
#define maxn 20
int n;
int a[m+5];
int ans;
vector<int> vec;
bool judge(int y[],int x){
for(int i=0;i<m;i++){
if(a[i]&(y[i]>>x)) return false;
}
return true;
}
void init() {
vec.clear();
memset(a,0,sizeof(a));
ans=200;
bool flag=false;
for(int i=0; i<m; i++) {
char s[maxn+5];
scanf("%s",s);
for(int j=0; j<n; j++) {
if(s[j]=='X') {
a[i]|=(1<<j);
}
}
}
for(int i=1;i<=n;i++){
if(judge(a,i)) vec.push_back(i);
}
return ;
}
void dfs(int step,int clk,int tbl[m+5]) {
if(step==t) {
ans=min(ans,clk+n);
return ;
}
for(int i=0;i<vec.size(); i++) {
if(clk+vec[i]+n+(t-step-1)*vec[0]>=ans) return ;
if(judge(tbl,vec[i])){
int x[m+5];
memcpy(x,tbl,sizeof(x));
for(int j=0;j<m;j++){
x[j]=a[j]|(x[j]>>vec[i]);
}
dfs(step+1,clk+vec[i],x);
}
}
}
int main() {
freopen("7.8 690.in","r",stdin);
freopen("7.8 690.out","w",stdout);
while(scanf("%d",&n)==1&&n!=0) {
init();
dfs(0,0,a);
printf("%d\n",ans);
}
return 0;
}