POJ - 1696 Space Ant

传送门:Space Ant

题意

给出n个点,有一个小人,他每次只能往左边拐,并且不能走以前走过的路,走的路线也不能相交,问他怎么走可以走的路程最大。

题解

可以想到肯定是所有的点都走到路径会最大,然后就很容易想到这不就可以一直凸包了吗!!每次形成凸包的点删掉再继续凸包,然后每次把点的编号加入队列中,直到没有点没被走过。我用的是graham算法的凸包,先找到纵坐标最小的点,第一次按照极角排序是判断和该点连线的极角,后边都是和前一次凸包里的最后一个点的连线形成的极角判断。(想法很简单,实现好麻烦....)

代码

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<math.h>
#include<iostream>
#define ll long long
using namespace std;

const ll maxn=1e3+10;

struct node
{
    ll x,y;
    ll id;
}p[maxn],s[maxn],q[maxn];

ll xx,yy;

ll cross(node a,node b,node c)
{
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}

ll cmp1(node a,node b)
{
    if(a.y==b.y) return a.x<b.x;
    return a.y<b.y;
}

ll cmp2(node a,node b)
{
    if(atan2(a.y-yy,a.x-xx)-atan2(b.y-yy,b.x-xx)==0) return a.x<b.x;
    else return atan2(a.y-yy,a.x-xx)<atan2(b.y-yy,b.x-xx);
}

queue<ll>qq;
bool vis[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        memset(vis,0,sizeof(vis));
        while(!qq.empty()) qq.pop();
        ll n;
        cin>>n;
        for(ll i=0;i<n;i++){
            cin>>q[i].id>>q[i].x>>q[i].y;
            p[i]=q[i];
        }
        sort(q,q+n,cmp1);
        ll id;
        xx=q[0].x,yy=q[0].y,id=q[0].id;
        qq.push(q[0].id);
        vis[q[0].id]=1;
        while(1){
            ll l=0;
            for(ll i=0;i<n;i++) if(!vis[q[i].id]) p[l++]=q[i];
//            cout<<l<<endl;
            if(!l) break;
            sort(p,p+l,cmp2);
            if(l==1) {qq.push(p[0].id);break;}
            else if(l==2) {qq.push(p[0].id),qq.push(p[1].id);break;}
            else{
                s[0].x=xx,s[0].y=yy,s[0].id=id;s[1]=p[0];
                ll top=1;
                for(ll i=1;i<l;i++){
                    while(top&&cross(s[top-1],s[top],p[i])<=0) top--;    //<=可以去掉重边
                    //如果是向右转,这个中间点就不是我们要找的点
                    s[++top]=p[i];//如果是向左转,就加进来
                }
                for(ll i=0;i<=top;i++){
                    if(!vis[s[i].id]) qq.push(s[i].id);
                    vis[s[i].id]=1;
                }
                xx=s[top].x,yy=s[top].y,id=s[top].id;
            }
        }
        cout<<qq.size();
        while(!qq.empty()) {
            cout<<' '<<qq.front();
            qq.pop();
        }
        cout<<endl;
    }
    return 0;
}
全部评论
TQL
点赞 回复 分享
发布于 2020-09-29 13:14

相关推荐

已经入职字节快一个月了,突然想起来之前那段时间的面经没有发,先发一下timeline吧。Tiktok&nbsp;内容安全平台(人才库电话捞我):电话10.28&nbsp;-&gt;&nbsp;一面10.30(我觉得你跟我们组业务挺match的,然后过了三天问hr挂了,应该是别人流程更快)阿里淘天:投递11.11-&gt;约面11.12-&gt;一面11.14(问得很简单,30分钟,手撕八股全过无后续)Kpi面腾讯wxg&nbsp;微信小程序:投递11.13&nbsp;-&gt;约面11.14-&gt;&nbsp;一面11.17&nbsp;(究极无敌拷打,问我多模态大模型涉及的算法?但是人很好)-&gt;11.19流程终止小红书&nbsp;风控平台:投递11.16&nbsp;—约面11.17&nbsp;&nbsp;-&gt;一面11.18&nbsp;(抽象的面试官,面试感觉一般,问得前端网页安全相关的,确实没准备)-&gt;11.20挂百度&nbsp;百家号:投递11.14&nbsp;—&gt;约面11.14&nbsp;-&gt;一面11.14(当场约2面)-&gt;二面11.24-&gt;口头告知offer,&nbsp;拒绝(原因是业务不太好)美团&nbsp;技术平台投递11.17&nbsp;-&gt;&nbsp;约面(忘记了,没多久)&nbsp;-&gt;一面11.19&nbsp;-&gt;二面11.21&nbsp;(字节offer不想面了)快手&nbsp;电商业务投递11.17&nbsp;-&gt;&nbsp;约面11.18&nbsp;-&gt;一面11.19&nbsp;-&gt;&nbsp;二面11.21(拒了)腾讯wxg&nbsp;微信支付(被捞):(直接发面试邮件)技术一面12.05&nbsp;-&gt;技术二面12.11&nbsp;-&gt;技术三面12.17&nbsp;-&gt;&nbsp;hr面已拒绝(了解业务后拒绝,但是有转正hc,感觉还蛮可惜)字节跳动&nbsp;xxxx:东家就不放具体的时间线了,大概是面完第二天就能知道结果,除了有几天ld请假了没填面评。不去wxg还有个原因是还在期末周,深圳学校来回太麻烦了,至少现在在的组感觉能学到很多的东西,自己的选择应该也没错。还是感概一下,一年前大二的时候投简历海投基本上石沉大海,无论大小厂约面比例很少。现在基本上投了就有面试,还都是以前梦寐以求的大厂,现在自己也有了更多的选择,也没有投太多简历。也感谢上一段实习的经历,很有意思的项目,无论是字节,腾讯,还是美团基本都有聊这个项目。面经需要等一下,也许等周末有空了再发给各位uu,感兴趣可以关注一下~有想要交流学习的同学也可以私信我,目前人在北京大钟寺~,可以找搭子~
正能量的牛可乐:这么多大厂面试下来,不仅摸清了不同公司的面试风格,还能精准避雷业务不匹配的岗位,血赚
实习简历求拷打
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务