您的位置:首页 > 产品设计 > UI/UE

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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: