bnuoj 1071 拼图++(BFS+康拓展开)

http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071

【题意】:经过四个点的顺逆时针旋转,得到最终拼图

【题解】:康拓展开+BFS,注意先预处理,得到所有状态,然后用hash来调用存在的状态

【code】:

 #include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h> using namespace std;
#define N 363000 struct Nod
{
int b[];
int pos;
}nd1,nd2; int fac[] = {,,,,,,,,,}; //康拓展开用到的数组
//康托展开:
int cantor(int* a, int k)
{
int i, j, tmp, num = ;
for (i = ; i < k; i++) {
tmp = ;
for (j = i + ; j < k; j++)
if (a[j] < a[i])
tmp++;
num += fac[k - i - ] * tmp;
}
return num;
} int mark[N],pre[N];
char dir[N];
int cx[]={,,,};
int cy[]={,,,}; void exchange(int *a,int x,int y,int n) //旋转
{
int temp;
if(n%)
{
temp = a[*x+y];
a[*x+y] = a[*x+y+];
a[*x+y+] = a[*(x+)+y+];
a[*(x+)+y+] = a[*(x+)+y];
a[*(x+)+y] = temp;
}
else
{
temp = a[*(x+)+y];
a[*(x+)+y] = a[*(x+)+y+];
a[*(x+)+y+] = a[*x+y+];
a[*x+y+] = a[*x+y];
a[*x+y] = temp;
}
} void bfs(int *b) //广度优先搜索
{
queue<Nod> q;
memset(mark,,sizeof(mark));
memset(pre,,sizeof(pre));
memcpy(nd1.b,b,sizeof(int)*);
int i,temp;
temp = cantor(b,);
mark[temp] = ;
nd1.pos = temp;
q.push(nd1);
while(!q.empty())
{
nd2 = q.front();
q.pop();
for(i=;i<;i++)
{
memcpy(nd1.b,nd2.b,sizeof(int)*);
exchange(nd1.b,cx[i/],cy[i/],i);
temp = cantor(nd1.b,);
if(mark[temp]!=)
{
mark[temp] = ;
pre[temp] = pre[nd2.pos]+;
nd1.pos = temp;
q.push(nd1);
}
}
}
} int main()
{
char str[];
int a[],b[]={,,,,,,,,},c[],hash[];
bfs(b);
int t;
scanf("%d",&t);
while(t--)
{
int i;
for(i=;i<;i++)
{
scanf("%d",a+i);
hash[a[i]] = i+; //hash
}
for(i=;i<;i++)
{
scanf("%d",c+i);
c[i] = hash[c[i]];
}
int temp = cantor(c,);
printf("Number Of Move(s) Needed: %d\n",pre[temp]);
}
return ;
}
上一篇:jQuery Mobile Datepicker 使用


下一篇:玩转android自定义控件二——自定义索引栏listview