这里是引用
问题描述
一个叫Andy的小朋友在一个正方形的沙漠中迷路了,身边的水也喝完了。Andy知道自己要渴死了,闲得无聊,所以他开始计算一些有趣的问题。
这个沙漠是由一个n*n的网格图构成的,当你站在某一个格子时,你可以走向周围八个格子中的一个。然而,沙漠中的某些格子有毒蛇,你必须避开他们,某些格子有水源,水源就是生命。
现在,Andy希望计算出每个格子到最近的水源的距离。你只需计算出所有距离的和即可。
输入格式
输入的第一行包含三个整数n, m,p,n表示沙漠的边长。m表示毒蛇的个数,p表示绿洲的个数。
接下来m行,输入m个毒蛇的坐标。一行一个
在接下来p行,输入p个绿洲的坐标。一行一个
输出格式
输出一个数,表示沙漠中每个坐标上避开毒蛇,找到绿洲的最短路径长度之和。
若坐标上有毒蛇,或无法从此坐标出发找到绿洲,长度记为-1.
若此坐标上有绿洲,长度记为0.
样例输入
3 1 2
2 1
1 3
3 2
样例输出
6
评测用例规模与约定
对于60%的数据,0<p<=5。
对于100%的数据,0<n<=3000, 0<p<=3000。
————————————————
#include<stdio.h>
int a[3009][3009]={0};
int b[9999999]={0},c[9999999]={0},d[9999999]={0},e[9999999]={0};
int n,m;
long int p;
void ccc(long int g,int w)//g代表有多少个须要广搜的数据 w代表第几次便利
{
long int i,j;
if(g!=0){
long int t=0;
for(i=0;i<g;i++){
if(c[i]+1<n)//shang
if(a[b[i]][c[i]+1]==0)
{
a[b[i]][c[i]+1]=w;
d[t]=b[i];e[t]=c[i]+1;
t++;
}
if(c[i]+1<n&&b[i]+1<n)
if(a[b[i]+1][c[i]+1]==0)
{
a[b[i]+1][c[i]+1]=w;
d[t]=b[i]+1;e[t]=c[i]+1;
t++;
}
if(b[i]+1<n)//you
if(a[b[i]+1][c[i]]==0)
{
a[b[i]+1][c[i]]=w;
d[t]=b[i]+1;e[t]=c[i];
t++;
}
if(b[i]+1<n&&c[i]-1>=0)
if(a[b[i]+1][c[i]-1]==0)
{
a[b[i]+1][c[i]-1]=w;
d[t]=b[i]+1;e[t]=c[i]-1;
t++;
}
if(c[i]-1>=0)//xia
if(a[b[i]][c[i]-1]==0)
{
a[b[i]][c[i]-1]=w;
d[t]=b[i];e[t]=c[i]-1;
t++;
}
if(c[i]-1>=0&&b[i]-1>=0)
if(a[b[i]-1][c[i]-1]==0)
{
a[b[i]-1][c[i]-1]=w;
d[t]=b[i]-1;e[t]=c[i]-1;
t++;
}
if(b[i]-1>=0)//zuo
if(a[b[i]-1][c[i]]==0)
{
a[b[i]-1][c[i]]=w;
d[t]=b[i]-1;e[t]=c[i];
t++;
}
if(c[i]+1<n&&b[i]-1>=0)
if(a[b[i]-1][c[i]+1]==0)
{
a[b[i]-1][c[i]+1]=w;
d[t]=b[i]-1;e[t]=c[i]+1;
t++;
}
}
for(i=0;i<t;i++)
{
b[i]=d[i];
d[i]=0;
c[i]=e[i];
e[i]=0;
}
ccc(t,w+1);
}
}
main()
{
long int as=0;
int i,j,z,x;
scanf("%d",&n);scanf("%d",&m);scanf("%d",&p);
for(i=0;i<m;i++)
{
scanf("%d",&z);
scanf("%d",&x);
a[z-1][x-1]=-1;
}
for(i=0;i<p;i++)
{
scanf("%d",&z);
scanf("%d",&x);
a[z-1][x-1]=-2;
b[i]=z-1;
c[i]=x-1;
}
ccc(p,1);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(a[i][j]==-2)
as=0+as;
else if(a[i][j]==0)
as=-1+as;
else if(a[i][j]==-1)
as=-1+as;
else
as=as+a[i][j];
}
}
printf("%ld",as);
return 0;
}