2014 UESTC Training for Search Algorithm K
2014-05-16 17:05
337 查看
状态定义是如果当前位置和目标位置一致对应二进制数为1,否则为0.利用这个二进制数字对应10进制数字vis判断。BFS
最开始做的时候是用二维做的,同时预处理出所有图形不重复的颜色,处理所有可填充的矩形(比如N=3,那么预处理矩形1*1,1*2,1*3,2*1,2*2,2*3),
在BFS中每次枚举颜色,矩形的左上角(填充起点),矩形类型(长宽)。尝试加入队列然后判断终点,果断T了。。
其实可以不管填充矩形的颜色有多少种,总共就2行,那么矩形填充就是1行,2行填充
然后一维处理;
每次的起点就是当前队列节点2*N中的每一个颜色,就尝试用这个颜色来涂色,如果当前位置颜色就是目标颜色,不执行涂色,那么直接continue
否则可以先尝试用这个颜色单行向左涂色,或者单行向右涂色。如果遇到目标颜色,那么跳出循环,否则修改二进制对应位(目标位置也为当前颜色那么置1)
接下来就要尝试涂2行的矩形,同样的方式,如果下一列的两个元素全部是与目标序列相同那么continue,否则尝试2行的矩形左涂右涂。对应修改位(目标位置也为当前颜色那么置1)
如此BFS模拟找到最终状态值dest=(1<<(2*N))-1;即可
节点只需要一个状态值一个dist
最开始做的时候是用二维做的,同时预处理出所有图形不重复的颜色,处理所有可填充的矩形(比如N=3,那么预处理矩形1*1,1*2,1*3,2*1,2*2,2*3),
在BFS中每次枚举颜色,矩形的左上角(填充起点),矩形类型(长宽)。尝试加入队列然后判断终点,果断T了。。
其实可以不管填充矩形的颜色有多少种,总共就2行,那么矩形填充就是1行,2行填充
然后一维处理;
每次的起点就是当前队列节点2*N中的每一个颜色,就尝试用这个颜色来涂色,如果当前位置颜色就是目标颜色,不执行涂色,那么直接continue
否则可以先尝试用这个颜色单行向左涂色,或者单行向右涂色。如果遇到目标颜色,那么跳出循环,否则修改二进制对应位(目标位置也为当前颜色那么置1)
接下来就要尝试涂2行的矩形,同样的方式,如果下一列的两个元素全部是与目标序列相同那么continue,否则尝试2行的矩形左涂右涂。对应修改位(目标位置也为当前颜色那么置1)
如此BFS模拟找到最终状态值dest=(1<<(2*N))-1;即可
节点只需要一个状态值一个dist
#include <map> #include <set> #include <list> #include <cmath> #include<cctype> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } struct node { int Hash; int dist; }q[100003]; char G[20]; bool vis[67000]; int dest; int N; int bfs() { memset(vis,false,sizeof(vis)); vis[0]=true; q[0].dist=q[0].Hash=0; int front=0,rear=1; while (front<rear) { node u=q[front]; int tmp=u.Hash; for (int i=0;i<2*N;i++) { int t=tmp; if (t&(1<<i)) continue;//当前位置已经是目标状态 for (int j=i;j<(i/N+1)*N;j++)//当前处于第一行第二行的情况,向右扫 { if (t&(1<<j)) break; if (G[i]==G[j]) t|=(1<<j);//当前位置置1,模拟涂色 } for (int j=i-1;j>=(i/N)*N;j--)//向左边扫 { if (t&(1<<j))break; if (G[i]==G[j]) t|=(1<<j); } if (t==dest) return u.dist+1; if (!vis[t]) { vis[t]=true; q[rear].dist=u.dist+1; q[rear].Hash=t; rear++; } if (i>=N) continue; //下面画两行的矩形 t=tmp; if (t&(1<<(i+N))) continue;//对应位置已经是目标图形 for (int j=i;j<N;j++) { if (t&(1<<j) | (t&(1<<(j+N)))) break;//当前点或者其下方已经达最终状态 if (G[i]==G[j]) t|=(1<<j); if (G[i]==G[j+N]) t|=(1<<(j+N)); } for (int j=i-1;j>=0;j--) { if (t&(1<<j) | (t&(1<<(j+N)))) break;//当前点或者其下方已经达最终状态 if (G[i]==G[j]) t|=(1<<j); if (G[i]==G[j+N]) t|=(1<<(j+N)); } if (t==dest) return u.dist+1; if (!vis[t]) { vis[t]=true; q[rear].dist=u.dist+1; q[rear].Hash=t; rear++; } } front++; } return 0; } int main() { //freopen("sample.txt","r",stdin); int T; scanf("%d",&T); int kase=1; while (T--) { scanf("%d",&N); dest=(1<<(2*N))-1; //printf("%d\n",dest); scanf("%s%s",G,G+N); printf("Case #%d: %d\n",kase++,bfs()); } return 0; }
相关文章推荐
- 2014 UESTC Training for Search Algorithm Problem D 方老师与素数
- 2014 UESTC Training for Search Algorithm I
- 2014 UESTC Training for Search Algorithm J
- 2014 UESTC Training for Search Algorithm L
- 2014 UESTC Training for Search Algorithm B
- 2014 UESTC Training for Search Algorithm C
- 2014 UESTC Training for Search Algorithm
- 2014 UESTC Training for Search Algorithm F
- 2014 UESTC Training for Search Algorithm Problem F 方老师与迷宫
- 2014 UESTC Training for Search Algorithm E
- 2014 UESTC Training for Search Algorithm Problem A 解救小Q
- 2014 UESTC Training for Search Algorithm H
- UESTC_Infected Land 2015 UESTC Training for Search Algorithm & String<Problem G>
- UESTC Training for Search Algorithm——B
- UESTC_王之迷宫 2015 UESTC Training for Search Algorithm & String<Problem A>
- UESTC_全都是秋实大哥 2015 UESTC Training for Search Algorithm & String<Problem J>
- UESTC Training for Search Algorithm——C
- 2016 UESTC Training for Search Algorithm & String A - Xiper的奇妙历险(1) 八皇后问题、dfs
- 2015 UESTC Training for Search Algorithm & String - M - Palindromic String【Manacher回文串】
- UESTC_邱老师降临小行星 2015 UESTC Training for Search Algorithm & String<Problem B>