心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0

在一个夜黑风高,伸手不见五指的深夜,睡梦中的林月如突然听到房外一阵躁动。她出去一看,发现一个女飞贼抢了一个古董商的包袱。
"站住!"
"那你为什么不来追我?"
"因为程序设计,在李大哥来之前,我不能追你。"
"那李逍遥为什么不来呢?"
"大概程序出bug了吧"
………………………………………………
终于,在等了一个又一个时辰后,林月如终于忍不住了,开始向女飞贼发起进攻。
"喂!你为什么可以动???"
"这大概也是一个bug吧!"
"不公平啊!"
"废话少说。"

已知林月如和女飞贼站在一个矩阵中,矩阵中有某些障碍物不可穿越。月如使出的铜钱镖可攻击8个方向,但不可穿越障碍物(可视为不能穿墙的重狙)。每个单位时间,月如可向上下左右4个方向移动一格,攻击不浪费时间。当然,月如想尽快结束这场无聊的战斗,所以她想在最短的时间内消灭女飞贼。

第一行为2个数N,M表示矩阵的规模(N为高,M为宽)。
接下来是N*M的矩阵,O表示空地,X表示障碍物。
下面是若干行数据,每行为一对数据,分别是女飞贼的位置和林月如的位置,显然她们都不可能在障碍物上。

每一组数据输出一行,仅一个整数,表示能消灭掉女飞贼的最短时间。
显然若能直接打到女飞贼,则时间为0。
若无法消灭,则输出"Impossible!"。(不含引号)

对于30%的数据,有N*M<=100
对于50%的数据,有N*M<=400
对于100%的数据,有N*M<=20000
对于100%的数据,测试数据组数不超过20组

本来可以一次AC的题目,一些比较具有相似性的句子在复制的时候忘了修改了,把'+'写成了'-',第一次提交只得了30分,百思不得其解……

我的思路是广搜出月如所在的点可以到达的其他点需要多少时间可以到达,然后把女飞飞所在的点向八个方向扩展,ans=maxint,ans=min(ans,s[i][j])。m*n<=20000,二维数组[20000][20000]肯定会爆,应该用一维数组表示,但是数据很弱,用[200][200]可以AC。

以下是我的代码:

#include<stdio.h>
#define min(a,b) (a<b?a:b)
#define maxint 200000000
/*
0 可到达的点 
-1 障碍物 
maxint 不可到达的点 
*/

struct queue
{
    
long xi[20001],yi[20001],front,rear,count;
}
q;
int empty()
{
    
return (q.count==0);
}

void clear()
{
    q.front
=0;
    q.rear
=-1;
    q.count
=0;
}

void put(long x,long y)
{
    q.count
++;
    q.rear
++;
    q.xi[q.rear]
=x;
    q.yi[q.rear]
=y;
}

void get(long *x,long *y)
{
    q.count
--;
    
*x=q.xi[q.front];
    
*y=q.yi[q.front];
    q.front
++;
}

int main()
{
    
char tmp,ch,map[201][201];
    
long m,n,x1,y1,x2,y2,i,j,xx,yy,s[201][201]={0};
    
long xd[]={0/**/,-1,-1,0,1,1,1,0,-1};
    
long yd[]={0/**/,0,1,1,1,0,-1,-1,-1};

    scanf(
"%ld%ld\n",&m,&n);
    
for(i=1;i<=m;i++)
    
{
      
for(j=1;j<=n;j++)
         scanf(
"%c",&map[i][j]);
      scanf(
"%c",&tmp);
    }

    scanf(
"%ld %ld %ld %ld",&x1,&y1,&x2,&y2);
    
//------Read In
    while(x1!=0||x2!=0||y1!=0||y2!=0)
    
{
       
//------BFS
       long ans=maxint;
       clear();
       
for(i=1;i<=m;i++)
         
for(j=1;j<=n;j++)
         
{
            
if(map[i][j]=='O')
              s[i][j]
=maxint;
            
else if(map[i][j]=='X')
              s[i][j]
=-1;
         }

       s[x2][y2]
=0;
       put(x2,y2);
       
while(!empty())
       
{
          
get(&xx,&yy);
          
if(xx>=2&&s[xx-1][yy]!=-1&&s[xx-1][yy]==maxint&&(xx-1!=x2||yy!=y2))
          
{
             put(xx
-1,yy);
             s[xx
-1][yy]=s[xx][yy]+1;
          }

          
if(xx+1<=m&&s[xx+1][yy]!=-1&&s[xx+1][yy]==maxint&&(xx+1!=x2||yy!=y2))
          
{
             put(xx
+1,yy);
             s[xx
+1][yy]=s[xx][yy]+1;
          }

          
if(yy>=2&&s[xx][yy-1]!=-1&&s[xx][yy-1]==maxint&&(xx!=x2||yy-1!=y2))
          
{
             put(xx,yy
-1);
             s[xx][yy
-1]=s[xx][yy]+1;
          }

          
if(yy+1<=n&&s[xx][yy+1]!=-1&&s[xx][yy+1]==maxint&&(xx!=x2||yy+1!=y2))
          
{
             put(xx,yy
+1);
             s[xx][yy
+1]=s[xx][yy]+1;
          }

       }

       
for(i=1;i<=8;i++)
       
{
          xx
=x1+xd[i];
          yy
=y1+yd[i];
          
while( s[xx][yy]!=-1 && xx>=1 && xx<=&& yy>=1 && yy<=n )
          
{
             ans
=min(ans,s[xx][yy]);
             xx
+=xd[i];
             yy
+=yd[i];
          }

       }

       
if(ans!=maxint)
          printf(
"%ld\n",ans);
       
else
          printf(
"Impossible!\n");
       scanf(
"%ld %ld %ld %ld",&x1,&y1,&x2,&y2);
    }

return 0;
}

posted on 2010-01-06 18:36 lee1r 阅读(1020) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:搜索

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理