您的位置:首页 > 其它

POJ - 3083 Children of the Candy Corn 解题报告

2017-01-21 11:04 176 查看
第一次写题解,也不能算是题解吧,就是自己做题的一些感受和过程中遇到的问题,暂时就是给自己看。也许这就是大家口中所谓的水题吧,但是题生来就不应该受到歧视,维护和保障题的权益从我做起!(他们说的水题我觉得也很难啊



另外,写代码的过程中的注释我也没删,全部保留了。

学长说代码要过程化还是什么的,具体名词我忘了,反正好像意思就是要多写函数。然后写的时候,还是传那个变量进去有点纠结,应该是熟练功的问题吧。

首先一开始读题的时候,有个事情就想不明白,就是这个left和rigth是怎么个走法。然后根据两个样例试了一下,好像意思就是一直往左转和往右转。然后总结出两种等价的走法。第一种就是,分情况,然后讨论,对应出每种情况的走法。比较麻烦,然后就是写if语句。我用的是第二种,对于一个点,根据这个点的上一个点的位置,确定出要走的方向,然后在这个点上,left就是在这个点上向左转(对于原来的方向来说),如果左转有墙就转顺时针向另一个方向。right就是相反,也就是向右转,有墙就逆时针找下一个方向。然后想到,那起点的方向怎么确定,根据“”我认为,从起点开始走的第一步是唯一确定的。而且起点和终点是不可能在四个角上面的。然后题目还提了一句,对于任意一个地图,只要终点是在边缘,就一定可以到达,我觉得可能是我那段话的意思理解不对吧,因为如果是一个圈,就会死循环。但是感觉这个走法对于符合某种限制的图来说,还是不错的。有时间仔细想一下这个限制是什么。大概的一个思路就是,这个方法最差的情况就是,把每个墙都怼了一遍,也就算是这个方法的思路就是怼所有的墙,就怼到终点了。。。。。(具体证明会陆续跟上)

广搜很明显,2次模拟+1次广搜。

值得注意的问题是,一定要注意,左右是关于从上一个点走到这一个点,两点连线的方向来说的。四个方向取模的时候,出了问题,因为负数取绝对值再取模和整数连起来不是满足周期性的。多组测试数据每次不止数组要清零,而且队列要删除重新创建。

两个队列同步分别储存x,y;从而存下每个点(的位置)。

实现代码的时候,这个while(1)的循环要做的事就是,从上一个点,到下一个点,相应的变量一定都要变成对应的下一个。

#include
#include
#include
#define N 50
/*
1.数组记得清0
2.输入时是不是要加那个空格
3.关于方向的规定上1右2下3左0
*/
using namespace std;
char a

={0};
int dis

={0};
int vis

={0};

int x,y,f=-1;//模拟时此时点的位置及方向

void shuru(int w,int h)//输入函数
{
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
cin>>a[i][j];
}
}
}

void k(int t)//对于一个所在的点,走一步并记录这次步数
{
if(t==1)y--;
if(t==2)x++;
if(t==3)y++;
if(t==0)x--;
}

int is_zou(int t)
{
if(t==0)
{
if(a[y][x-1]=='.'||a[y][x-1]=='E'){f=t;x--;return 1;}
else return 0;
}
if(t==1)
{
if(a[y-1][x]=='.'||a[y-1][x]=='E'){f=t;y--;return 1;}
else return 0;
}
if(t==2)
{
if(a[y][x+1]=='.'||a[y][x+1]=='E'){f=t;x++;return 1;}
else return 0;
}
if(t==3)
{
if(a[y+1][x]=='.'||a[y+1][x]=='E'){f=t;y++;return 1;}
else return 0;
}
}

int l(int w,int h,int zuoyou)//zuoyou==1则向右转
{
int l=0;//要返回的值
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
if(a[i][j]=='S')
{
x=j;y=i;
break;
}
}
}
if(x==1)f=2;//根据题意S不应该在角上
if(x==w)f=0;
if(y==1)f=3;
if(y==h)f=1;
k(f);
if(zuoyou==1)//向右的情况
{
while(1)
{
l++;
for(int i=f+1;;i--)//顺时针旋转
{
if(is_zou((i+16)%4))break;//如果可以走,就走到下一步;(xyf的值随之改变)
}
//cout<qx;
queueqy;
for(int i=1;i<=h;i++)//找到起点
{
for(int j=1;j<=w;j++)
{
if(a[i][j]=='S')
{
x=j;y=i;
break;
}
}
}
qx.push(x);
qy.push(y);
dis[y][x]=1;
vis[y][x]=1;
int ax[]={0,0,-1,1};
int ay[]={1,-1,0,0};
while(1)
{
x=qx.front();
y=qy.front();
for(int i=0;i<4;i++)
{
if(a[ y+ay[i] ][ x+ax[i] ]=='E')return dis[y][x]+1;
if(vis[ y+ay[i] ][ x+ax[i] ]==0 && a[ y+ay[i] ][ x+ax[i] ]=='.')
{
dis[ y+ay[i] ][ x+ax[i] ]=dis[y][x]+1;
vis[ y+ay[i] ][ x+ax[i] ]=1;
qx.push(x+ax[i]);
qy.push(y+ay[i]);
}
}
qx.pop();
qy.pop();
}

}

int main()
{
int n;
cin>>n;
while(n--)
{
int w,h;
cin>>w>>h;
shuru(w,h);
cout<


这次主要还是代码实现的问题。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm