uva 690(位运算+搜索)
反着存图,太tm神了......看了我一晚上才懂
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int m=5; const int maxn=100; char str[maxn]; int jump[maxn]; int w[7]; int n,cnt,ans; bool judge(int s[],int x) { for(int i=0;i<m;i++) { if((s[i]>>x)&w[i]) return 0; } return 1; } void init() { cnt=0; ans=n*10; memset(w,0,sizeof(w)); for(int i=0;i<m;i++) { gets(str); for(int j=0;j<n;j++) if(str[j]=='X') { w[i]|=(1<<j);//反着存,目的是使向右移动就是向左移动 } } for(int i=0;i<=n;i++) if(judge(w,i)) { jump[cnt++]=i; } } void dfs(int s[],int d,int sum) { if(d==10) { ans=min(ans,sum); return; } if(sum+(10-d)*jump[0]>ans) return; for(int i=0;i<cnt;i++) { int p[7]; if(judge(s,jump[i])) { for(int j=0;j<m;j++) p[j]=((s[j]>>jump[i])^w[j]);//向右移动,相当于正着存向左移动,也相当于w在原图上相对于向右移动 dfs(p,d+1,sum+jump[i]); } } } int main() { while(~scanf("%d",&n)&&n) { getchar(); init(); dfs(w,1,n); printf("%d\n",ans); } return 0; }