因为老师这周在讲比较形而上的NP问题,所以就让我们随便选题了,果断我就真随便选了,看了tag后才发现这是一道数学题,还是一道几何题,好吧,没这么严重,估计小学生都能想出一点东西来,直接上题吧
-----------------------题目--------------------
You are given an array x of n
positive numbers. You start at point (0,0)
and moves x[0]
metres to the north, then x[1]
metres to the west, x[2]
metres to the south, x[3]
metres to the east and so on. In other words, after each move your direction changes counter-clockwise.
Write a one-pass algorithm with O(1)
extra space to determine, if your path crosses itself, or not.
Example 1:
Given x = [2, 1, 1, 2]
,
┌───┐
│ |
└───┼──
|
Return true (self crossing)
Example 2:
Given x = [1, 2, 3, 4]
,
┌──────┐
│ |
│
│
└────────────>
Return false (not self crossing)
Example 3:
Given x = [1, 1, 1, 1]
,
┌───┐
│ |
└───┼>
Return true (self crossing)
------------------------题解-----------------------
题目的要求是给我们一个数组,数组的意思是从第一个数x【i】开始,按照上下左右的方向走x[i]这么长的距离,看这个路径会不会交叉,其实我觉得这个题和数学关系不大,但毕竟我也想不到更好的归类,好歹这还是和几何有点关系的。然后就开始想吧,最开始我只是想到了第一种情况:(灵魂画师登场)
上图中红色表示起点范围,蓝色表示终点范围,后来在一遍又一遍的提交中才逐渐补充了第二三种情况,我个人感觉是没有其他情况了,反正题目中就这三种情况,好了,到现在为止,这道题目也就没什么可讲的了,我连下标都给你们标出来了(请叫我雷锋)。反正只要判定这三种情况就好了,如果没有出现这三种情况就是不会自交了,出现任意一种就会自交。下面是我的代码
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
bool isSelfCrossing(vector<int>& x) {
int l=x.size();
if(l<4)
return false;
for(int i=0;i<l-3;i++)
{
if(x[i]>=x[i+2]&&x[i+1]<=x[i+3])return true;//第一种情况
if(l>4&&(x[i]+x[i+4]>=x[i+2])&&(x[i+1]==x[i+3]))return true;//第二种情况
if(l>5&&(x[i+2]>x[i+4]&&x[i+4]>=x[i+2]-x[i]&&x[i+3]<=x[i+1]+x[i+5]&&x[i+1]<x[i+3]))return true; //第三种情况
}
return false;
}
};
题目虽然是hard,但这道题只要慢慢试就一定能做出来的。
------------------------手动分割线------------------
see you next illusion