| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4928 人关注过本帖
标题:八数码问题
只看楼主 加入收藏
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
结帖率:79.37%
收藏
已结贴  问题点数:20 回复次数:8 
八数码问题
题目:http://acm.hdu.
杭电和北大上有同样的题目,但是杭电的数据比较强,北大的数据弱,我在做杭电的题:
1.用朴素的BFS(TLE)
2.使用预处理,先遍历18W+种情况,然后直接打印路径 如果该start在visit里没有被记录,那么就提示误解    (WA) :打印出来的路径不对,不知道是什么原因?
 
 
做北大的题:
1.用朴素的BFS(RE) 虽然没有TLE,但是评测系统提示数组越界

RQNOJ:
1.用朴素的BFS(AC) 数据很弱吧

朴素BFS:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
char queue[400000][10];
int s[400000];
char visit[400000];
int farther[400000];
char r[400000];
int fac[9]={1,1,2,6,24,120,720,5040,40320};
void print(int x,int end)
{
    if(x==end)
    return ;
    print(farther[x],end);
    printf("%c",r[x]);
}
int judge(int x,int y)
{
    if(x>=0&&x<3&&y>=0&&y<3)
    return 1;
    return 0;
}
int cantor(char s[])  
{  
    int i,j,t,sum=0;
    for(i=0;i<9;i++)
    {
    t=0;
    for (j=i+1;j<9;j++)  
    if(s[j]-'0'<s[i]-'0')  
    t++;
    sum=sum+t*fac[9-i-1];  
    }
    return sum;  
}
void bfs(char start[],char end[])
{
    int head=0,tail=1;
    int i,j,k,x,y,xx,yy,m,step,f;
    char temp;
    char temp1[10],temp2[3][3];
    char temp3[10];
    memset(queue,0,sizeof(queue));
    memset(visit,0,sizeof(visit));
    memset(r,0,sizeof(r));
    memset(farther,0,sizeof(farther));
    memset(s,0,sizeof(visit));
    strcpy(queue[0],start);
    while(head<tail)
    {
    strcpy(temp1,queue[head]);
    m=0;
    for(i=0;i<3;i++)
    for(j=0;j<3;j++)
    {
    temp2[i][j]=temp1[m++];
    if(temp2[i][j]=='0')
    x=i,y=j;
    }
    step=s[head];
    if(strcmp(temp1,end)==0)
    {
    print(cantor(end),cantor(start));
    //printf(" %d\n",step);
    printf("\n");
    return ;
    }
    head++;
    for(i=0;i<4;i++)
    {
    xx=x+dx[i];
    yy=y+dy[i];
    m=0;
    for(k=0;k<3;k++)
    for(j=0;j<3;j++)
    temp2[k][j]=temp1[m++];
    if(judge(xx,yy)==1)
    {
    temp=temp2[xx][yy];
    temp2[xx][yy]=temp2[x][y];
    temp2[x][y]=temp;
    m=0;
    for(k=0;k<3;k++)
    for(j=0;j<3;j++)
    temp3[m++]=temp2[k][j];
    f=cantor(temp3);
    if(visit[f]==1)
    continue;
    visit[f]=1;
    farther[f]=cantor(temp1);
    if(i==0)
    r[f]='u';
    else if(i==1)
    r[f]='r';
    else if(i==2)
    r[f]='d';
    else
    r[f]='l';
    strcpy(queue[tail],temp3);
    s[tail]=step+1;
    tail++;
    continue;
    }
    }
    }
    printf("unsolvable\n");
}
int main()
{
    int i,m;
    char temp[1000];
    char start[10],end[10];
    while(gets(temp))
    {
    for(i=0,m=0;i<strlen(temp);i++)
    if((temp[i]>='0'&&temp[i]<='9')||temp[i]=='x')
    {
    if(temp[i]!='x')
    start[m++]=temp[i];
    else
    start[m++]='0';
    }
    strcpy(end,"123456780");
    bfs(start,end);
    }
    //system("pause");
    return 0;
}

预处理BFS:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
char queue[400000][10];
char visit[400000];
int farther[400000];
char r[400000];
int fac[9]={1,1,2,6,24,120,720,5040,40320};
void print(int x,int end)
{
    if(x==end)
    return ;
    print(farther[x],end);
    printf("%c",r[x]);
}
int judge(int x,int y)
{
    if(x>=0&&x<3&&y>=0&&y<3)
    return 1;
    return 0;
}
int cantor(char s[])  
{  
    int i,j,t,sum=0;
    for(i=0;i<9;i++)
    {
    t=0;
    for (j=i+1;j<9;j++)  
    if(s[j]-'0'<s[i]-'0')  
    t++;
    sum=sum+t*fac[9-i-1];  
    }
    return sum;  
}
void bfs()
{
    int head=0,tail=1;
    int i,j,k,x,y,xx,yy,m,f;
    char temp;
    char temp1[10],temp2[3][3];
    char temp3[10];
    memset(queue,0,sizeof(queue));
    memset(visit,0,sizeof(visit));
    memset(r,0,sizeof(r));
    memset(farther,0,sizeof(farther));
    strcpy(queue[0],"123456780");
    while(head<tail)
    {
    strcpy(temp1,queue[head]);
    m=0;
    for(i=0;i<3;i++)
    for(j=0;j<3;j++)
    {
    temp2[i][j]=temp1[m++];
    if(temp2[i][j]=='0')
    x=i,y=j;
    }
    head++;
    /*for(i=0;i<3;i++)
    {
    printf("\n");
    for(j=0;j<3;j++)
    printf("%c",temp2[i][j]);
    }
    printf("\n");*/
    for(i=0;i<4;i++)
    {
    xx=x+dx[i];
    yy=y+dy[i];
    m=0;
    for(k=0;k<3;k++)
    for(j=0;j<3;j++)
    temp2[k][j]=temp1[m++];
    if(judge(xx,yy)==1)
    {
    temp=temp2[xx][yy];
    temp2[xx][yy]=temp2[x][y];
    temp2[x][y]=temp;
    m=0;
    memset(temp3,0,sizeof(temp3));
    for(k=0;k<3;k++)
    for(j=0;j<3;j++)
    temp3[m++]=temp2[k][j];
    f=cantor(temp3);
    if(visit[f]==1)
    continue;
    visit[f]=1;
    farther[f]=cantor(temp1);
    if(i==0)
    r[f]='u';
    else if(i==1)
    r[f]='r';
    else if(i==2)
    r[f]='d';
    else
    r[f]='l';
    strcpy(queue[tail],temp3);
    tail++;
    continue;
    }
    }
    }
    //printf("-1\n");
}
int main()
{
    int i,m;
    char temp[50];
    char start[10],end[10];
    bfs();
    strcpy(end,"123456780");
    while(gets(temp))
    {
    for(i=0,m=0;i<strlen(temp);i++)
    if((temp[i]>='0'&&temp[i]<='9')||temp[i]=='x')
    {
    if(temp[i]!='x')
    start[m++]=temp[i];
    else
    start[m++]='0';
    }
    if(visit[cantor(start)]==1)
    {
    print(cantor(start),cantor(end));
    printf("\n");
    }
    else
    printf("unsolvable\n");
    }
    //system("pause");
    return 0;
}

搜索更多相关主题的帖子: include visit start 北大 
2011-07-15 19:48
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
朴素BFS的思路:用康托展开判重,遍历所有情况,如果找到目标就return
预处理:先将所有的情况遍历,输入测试数据然后直接打印结果

本来打算再用逆序数优化的,但是在pku上没有AC,所以暂时没有优化

欢迎来到我的博客:http://blog..cn/noisunyuhong
2011-07-15 20:04
卧龙孔明
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:59
帖 子:3872
专家分:684
注 册:2006-10-13
收藏
得分:3 
这个题应该用A*
双向广度优先搜索效率也可
单纯的BFS对于单组数据很吃亏
另外,康托展开(即使你在用树状数组优化逆序对)对于单向BFS来说也不是最优的。

My Blog: www.aiexp.info
虽然我的路是从这里开始的,但是这里不再是乐土.感谢曾经影响过,引导过,帮助过我的董凯,飞燕,leeco,starwing,Rockcarry,soft_wind等等等等.别了,BCCN.
2011-07-17 17:54
w123012306
Rank: 9Rank: 9Rank: 9
来 自:湖南
等 级:蜘蛛侠
威 望:4
帖 子:307
专家分:1180
注 册:2010-4-22
收藏
得分:3 
真呀个帅!

楼上,楼下的一定要幸福开心哦!
2011-07-17 20:55
黄昏乐章
Rank: 2
来 自:青岛
等 级:论坛游民
帖 子:73
专家分:25
注 册:2011-6-6
收藏
得分:3 
这才是高手啊
2011-07-17 20:59
zanzan1986
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:100
专家分:140
注 册:2011-2-22
收藏
得分:3 
回复 3楼 卧龙孔明
是什么题目啊!能给我看看么?
2011-07-17 21:00
博士无双
Rank: 2
等 级:论坛游民
帖 子:32
专家分:65
注 册:2011-7-5
收藏
得分:3 
高手,刚开始学,太难了
2011-07-18 06:54
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:3 
A* 我学习了一段时间,发现和bfs是类似的,
bfs用的是标准队列, A*用的是优先队列,
Dijkstra 用的也是优先队列,
应该属于特殊的 A*,只是没有估价函数。
如果是迷宫的话,A*解起来会很简单,相当于殴几里德平面图搜索,


[ 本帖最后由 BlueGuy 于 2011-7-20 23:51 编辑 ]

我就是真命天子,顺我者生,逆我者死!
2011-07-20 23:24
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
三道题全部用朴素BFS过了,第一道题使用预处理,先将目标状态到各个状态全部遍历,然后输入测试数据后直接输出,第二题同理

欢迎来到我的博客:http://blog..cn/noisunyuhong
2011-07-21 09:08
快速回复:八数码问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017929 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved