3 3 ABA CBC 3 BAA CCB 3 BBB BAB
Case #1: 3 Case #2: 3 Case #3: 2
广搜题目,枚举起点,染色为对的颜色,然后向左至对的颜色,向右至对的颜色 然后上下两行一起
状态压缩 每行最多八个点 所以2^16可以将状态存储
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int t,n,tt; bool vis[2][8],tmp[2][8]; char ch[2][8]; bool flag[1<<16];//标记判重 struct node { int flag; int t; } st,ed; void set_vis(node a) //获得状态矩阵值 { memset(vis,false ,sizeof(vis)); int i=0; while(i<n) { vis[0][i]=(a.flag&1); a.flag/=2; i++; } i=0; while(i<n) { vis[1][i]=(a.flag&1); a.flag/=2; i++; } return ; } int get_flag() //获得状态压缩值 { int ans=0; for(int i=0; i<n; i++) { if(tmp[0][i]) ans|=(1<<i); if(tmp[1][i]) ans|=(1<<(i+n)); } return ans; } int l,r; void set_tmp(int x,int y) //找到最大改变区间 { l=y,r=y; while(l>=0&&!vis[x][l]) l--; while(r<n&&!vis[x][r]) r++; for(int i=l+1; i<r; i++) tmp[x][i]=(ch[x][y]==ch[x][i]); return ; } void bfs() { queue<node>q; q.push(st); while(!q.empty()) { st=q.front(); q.pop(); set_vis(st); if(st.flag==(1<<(n*2))-1) //全部染色对的情况 { printf("Case #%d: %d\n",tt++,st.t); return ; } for(int i=0; i<2; i++) { for(int j=0; j<n; j++) { if(!vis[i][j]) { memcpy(tmp,vis,sizeof(vis)); set_tmp(i,j); //枚举染色点 for(int k=l+1;k<r;k++) { tmp[i][k]=(ch[i][k]==ch[i][j]); ed.flag=get_flag(); if(!flag[ed.flag]) { ed.t=st.t+1; flag[ed.flag]=true ; q.push(ed); } } memcpy(tmp,vis,sizeof(vis)); //两行 for(int k=l+1;k<r;k++) { tmp[i][k]=(ch[i][k]==ch[i][j]); tmp[i^1][k]=(ch[i^1][k]==ch[i][j]); ed.flag=get_flag(); if(!flag[ed.flag]) { ed.t=st.t+1; flag[ed.flag]=true ; q.push(ed); } } } } } } return ; } int main() { cin>>t; tt=1; while(t--) { cin>>n; cin>>ch[0]>>ch[1]; memset(flag,0,sizeof(flag)); st.flag=0; st.t=0; flag[0]=true ; bfs(); } return 0; }