正文

[TOJ]1021麻将游戏2006-04-22 13:18:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/rickone/1775.html

分享到:

麻将游戏Time Limit:1s Memory Limit:1024k Total Submit:3119 Accepted:531 下载样例程序(PE)下载样例程序(ELF) --------------------------------------------------------------------------------Problem  在一种"麻将"游戏中,游戏是在一个有W*H格子的矩形平板上进行的。 每个格子可以放置一个麻将牌,也可以不放(如图所示)。玩家的目标是将平板上的所有可通过一条路径相连的 两张相同的麻将牌,从平板上移去。最后如果能将所有牌移出平板,则算过关。   这个游戏中的一个关键问题是:两张牌之间是否可以被一条路径所连接,该路径满足以下两个特性:   1. 它由若干条线段组成,每条线段要么是水平方向,要么是垂直方向。   2. 这条路径不能横穿任何一个麻将牌 (但允许路径暂时离开平板)。   这是一个例子:  在(1,3)的牌和在(4, 4)的牌可以被连接。(2, 3)和(3, 4)不能被连接。   你的任务是编一个程序,检测两张牌是否能被一条符合以上规定的路径所连接。 Input第一行为一整数N表示有N组测试数据。 每组测试数据的第一行有两个整数w,h (1<=w,h<=75),表示平板的宽和高。 接下来h行描述平板信息,每行包含w个字符,如果某格子有一张牌,则这个格子上有个'X',否则是一个空格。 平板上最左上角格子的坐标为(1,1),最右下角格子的坐标为(w,h)。 接下来的若干行,每行有四个数x1, y1, x2, y2 ,且满足1<=x1,x2<=w,1<=y1,y2<=h, 表示两张牌的坐标(这两张牌的坐标总是不同的)。 如果出现连续四个0,则表示输入结束。 Output输出文件中,对于每一对牌输出占一行,为连接这一对牌的路径最少包含的线段数。 如果不存在路径则输出0。 Sample Input15 4XXXXXX   XXXX XXXX 2 3 5 31 3 4 42 3 3 40 0 0 0Sample Output430Sourcesgoi#include<stdio.h>#include<string.h>#include<memory.h>unsigned char mazemap[77][10];unsigned char visited[77][10];#define getmap(x,y) (mazemap[y][x/8]&(1<<(7-x%8)))#define setmap(x,y) mazemap[y][x/8]|=1<<(7-x%8)#define blkmap(x,y) mazemap[y][x/8]&=~(1<<(7-x%8))#define getvis(x,y) (visited[y][x/8]&(1<<(7-x%8)))#define setvis(x,y) visited[y][x/8]|=1<<(7-x%8)int width,height;#define QueMax 5929typedef struct{ int data[QueMax][2]; int path[QueMax]; int front,rear,count;}MyQueue;MyQueue theque; void initQueue(MyQueue *que){ que->front=que->rear=que->count=0;}void EnQueue(MyQueue *que,int x,int y,int path){ if(que->count==QueMax) {  return; } que->data[que->rear][0]=x; que->data[que->rear][1]=y; que->path[que->rear]=path; que->rear++; que->count++; if(que->rear==QueMax)  que->rear=0;}void DeQueue(MyQueue *que,/*out*/int *x,int *y,int *path){ if(que->count==0) {  return; } *x=que->data[que->front][0]; *y=que->data[que->front][1]; *path=que->path[que->front]; que->front++; que->count--; if(que->front==QueMax)  que->front=0;}int EmptyQueue(MyQueue *que){ return que->count==0;}int getline(char *str){    char c;    while(1)    {        c=getc(stdin);        if(c==EOF)return 0;        if(c=='\n')break;        *str++=c;    }    *str='\0';    return 1;}void readmap(int w,int h){ int i,j; char buffer[256]; memset(mazemap,0,(h+2)*10); getc(stdin); for(i=0;i<h;++i) {  getline(buffer);  for(j=1;j<=w;++j)   if(buffer[j-1]=='X')    setmap(j,i+1); } width=w; height=h;}int pathlen(int x,int y,int x2,int y2){ int path=0,scan; memset(visited,0,(height+2)*10); setvis(x,y); initQueue(&theque); blkmap(x2,y2); while(x!=x2||y!=y2) {  path++;  for(scan=x-1;scan>=0&&getmap(scan,y)==0;scan--)  {   if(getvis(scan,y)==0)   {    EnQueue(&theque,scan,y,path);    setvis(scan,y);   }  }  for(scan=x+1;scan<=(width+1)&&getmap(scan,y)==0;scan++)  {   if(getvis(scan,y)==0)   {    EnQueue(&theque,scan,y,path);    setvis(scan,y);   }  }  for(scan=y-1;scan>=0&&getmap(x,scan)==0;scan--)  {   if(getvis(x,scan)==0)   {    EnQueue(&theque,x,scan,path);    setvis(x,scan);   }  }  for(scan=y+1;scan<=(height+1)&&getmap(x,scan)==0;scan++)  {   if(getvis(x,scan)==0)   {    EnQueue(&theque,x,scan,path);    setvis(x,scan);   }  }  if(EmptyQueue(&theque))  {   path=0;   break;  }  DeQueue(&theque,&x,&y,&path); } setmap(x2,y2); return path;}int main(){ int n,w,h,i; int x1,x2,y1,y2; scanf("%d",&n); for(i=0;i<n;++i) {  scanf("%d%d",&w,&h);  readmap(w,h);  while(1)  {   scanf("%d%d%d%d",&x1,&y1,&x2,&y2);   if(x1==0&&y1==0&&x2==0&&y2==0)    break;   printf("%d\n",pathlen(x1,y1,x2,y2));  } } return 0;} 终于AC了,AC的感觉真爽~~之前犯了一个逻辑错误,真难找啊~~之前我这样写的: for(scan=x-1;scan>=0&&getmap(scan,y)==0&&getvis(scan,y)==0;scan--)  {   EnQueue(&theque,scan,y,path);   setvis(scan,y);  }  /*right x*/  for(scan=x+1;scan<=(width+1)&&getmap(scan,y)==0&&getvis(scan,y)==0;scan++)  {   EnQueue(&theque,scan,y,path);   setvis(scan,y);  }  /*up y*/  for(scan=y-1;scan>=0&&getmap(x,scan)==0&&getvis(x,scan)==0;scan--)  {   EnQueue(&theque,x,scan,path);   setvis(x,scan);  }  /*down y*/  for(scan=y+1;scan<=(height+1)&&getmap(x,scan)==0&&getvis(x,scan)==0;scan++)  {   EnQueue(&theque,x,scan,path);   setvis(x,scan);  }  if(EmptyQueue(&theque))   return 0;  DeQueue(&theque,&x,&y,&path); } 这样会出现‘阻拦扫描’的BUG。

阅读(38760) | 评论(3)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册