题目见下:
输入样例
14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12
//输入上述数据后输出“Yes”
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define sz 100
typedef struct node{
int x, y;
}Node;
Node cro[sz];
set<int>win;
set<int>visited;
int check_start(int i, int d)//是否可以从岸上一步到达
{
if(pow(cro[i].x, 2.0) + pow(cro[i].y, 2.0) <= pow(d + 7.5, 2.0))
{
return 1;
}
return 0;
}
int check_jump(int i, int n, int d)//递归判断是否可逃出生天
{
visited.insert(i);
if(win.count(i))//主要是针对第一次调用就成功的情况
{
return 1;
}
int x = cro[i].x;
int y = cro[i].y;
for(int j=0; j<n ; j++)
{
if(visited.count(j)) continue;
int j_x = cro[j].x;
int j_y = cro[j].y;
if(pow(abs(j_x - x), 2.0) + pow(abs(j_y - y), 2.0) <= pow(d, 2.0))
{
if(win.count(j))
{
return 1;
}
if(check_jump(j, n, d))//递归遍历,类似DFS思想
{
return 1;
}
}
}
return 0;
}
int main()
{
int n, d;
cin>>n>>d;
for(int i=0; i<n; i++)
{
cin>>cro[i].x>>cro[i].y;
if(50 - abs(cro[i].x) <= d || 50 - abs(cro[i].y) <= d)
{
win.insert(i);
}
}
if(win.empty()) //没有到岸边距离小于步长的点,提前结束
{
cout<<"No";
return 0;//记得终止程序
}
for(int i=0; i<n; i++)
{
if(check_start(i, d) == 0) continue;//离岛太远
visited.clear();
if(check_jump(i, n, d))
{
cout<<"Yes";
return 0;
}
}
cout<<"No";
}
检查了半天仍然查不出的问题:
1. 当考虑特殊情况要提前结束程序时,别忘了return,不然继续运行后面的程序会导致奇怪的错误。//对应main中代码:
if(win.empty()) //没有到岸边距离小于步长的点,提前结束
{
cout<<"No";
return 0;//记得终止程序
}
2.对函数进行递归操作时,尤应注意考虑第一次调用(即函数第一次执行,还没有进入递归)是否就符合win的条件了。//对应check_jump中代码:
int check_jump(int i, int n, int d)//递归判断是否可逃出生天
{
visited.insert(i);
if(win.count(i))//主要是针对第一次调用就成功的情况
{
return 1;
}
}
~希望对你有启发~