Codeforces Gym 100341I Hungry Queen 2 Set+模拟

来源:互联网 发布:细高跟 知乎 编辑:程序博客网 时间:2024/05/21 09:02

题目大意:

在一个无穷大的棋盘上有一个皇后在(0,0)点,皇后可以上下左右或者沿对角线移动。有n个卒,皇后要按卒的输入顺序吃卒,每次移动必须吃掉一个卒,皇后不能跳过卒。问皇后最多能吃掉几个卒?

做法:

  • 先将所有卒的位置(x、y、x+y、x-y)离散化;
  • 用set分别记录,在同一行(按y排序)、同一列(按x排序)、同一对角线的卒;
  • 模拟皇后的移动,每次在当前位置与下一个卒的位置所确定的set中查找下一个卒的前驱和后继,如果前驱和后继中有一个是当前位置,这说明在当前位置与下一个卒的方向上没有障碍,答案+1;
  • 在所有方向的set中删掉当前点,然后移动到下一个点;
  • 反之,如果下一个卒与当前位置不能构成合法移动,或者在当前位置与下一个卒的方向上有障碍,那么就结束模拟输出答案。

代码:

4551665 Accepted 24532 498 GNU G++ 4.9.2 2606 5:06:16
#include <bits/stdc++.h>using namespace std;const int maxn=100001;int x[maxn],y[maxn],lx[maxn],ly[maxn],lxpy[maxn],lxmy[maxn];struct cmp2{    bool operator ()(int a,int b)const    {        return x[a]<x[b];    }};//按x排序 struct cmp1{    bool operator ()(int a,int b)const    {        return y[a]<y[b];    }};//按y排序 set<int,cmp1>mx[maxn],mxpy[maxn],mxmy[maxn];set<int,cmp1>::iterator ix,ipx;set<int,cmp2>my[maxn];set<int,cmp2>::iterator iy,ipy;int rp(int num,int l,int a[]){    return lower_bound(a,a+l,num)-a;}//返回离散化下标 int main(){    freopen("queen2.in","r",stdin);#ifdef ONLINE_JUDGE    freopen("queen2.out","w",stdout);#endif    int n;    scanf("%d",&n);    for(int i=0;i<n;i++)    {        scanf("%d%d",&x[i],&y[i]);        lx[i]=x[i];        ly[i]=y[i];        lxpy[i]=x[i]+y[i];        lxmy[i]=x[i]-y[i];    }    sort(lx,lx+n);    sort(ly,ly+n);    sort(lxpy,lxpy+n);    sort(lxmy,lxmy+n);    int sx=unique(lx,lx+n)-lx;    int sy=unique(ly,ly+n)-ly;    int sxpy=unique(lxpy,lxpy+n)-lxpy;    int sxmy=unique(lxmy,lxmy+n)-lxmy;    //离散化     int px=0,py=0;    for(int i=0;i<n;i++){        mx[rp(x[i],sx,lx)].insert(i);        my[rp(y[i],sy,ly)].insert(i);        mxpy[rp(x[i]+y[i],sxpy,lxpy)].insert(i);        mxmy[rp(x[i]-y[i],sxmy,lxmy)].insert(i);    }    //将同类点加到set中     //模拟移动     if(px==x[0] || py == y[0] || px+py ==x[0]+y[0] || px-py == x[0]-y[0]){        int ans=1,ans2=0;        px=x[0];py=y[0];        for(int i=1;i<n;i++)        {            ans2=ans;               if(px == x[i])            {                int pos=rp(x[i],sx,lx);                ix=++mx[pos].find(i);                if(ix!=mx[pos].end() && (*ix) == (i-1))++ans;                ipx=mx[pos].find(i);                if( ipx!=mx[pos].begin() )                    if(*(--ipx) == (i-1))++ans;            }else if(py == y[i])            {                int pos=rp(y[i],sy,ly);                iy=++my[pos].find(i);                if(iy!=my[pos].end() && (*iy) == (i-1))++ans;                ipy=my[pos].find(i);                if( ipy!=my[pos].begin() )                    if(*(--ipy) == (i-1))++ans;            }else if(px+py == x[i]+y[i])            {                int pos=rp(x[i]+y[i],sxpy,lxpy);                ix=++mxpy[pos].find(i);                if(ix!=mxpy[pos].end() && (*ix) == (i-1))++ans;                ipx=mxpy[pos].find(i);                if( ipx!=mxpy[pos].begin() )                    if(*(--ipx) == (i-1))++ans;            }else if(px-py == x[i]-y[i])            {                int pos=rp(x[i]-y[i],sxmy,lxmy);                ix=++mxmy[pos].find(i);                if(ix!=mxmy[pos].end() && (*ix) == (i-1))++ans;                ipx=mxmy[pos].find(i);                if( ipx!=mxmy[pos].begin() )                    if(*(--ipx) == (i-1))++ans;            }            else break;            if(ans==ans2)break;            mx[rp(px,sx,lx)].erase(i-1);            my[rp(py,sy,ly)].erase(i-1);            mxpy[rp(px+py,sxpy,lxpy)].erase(i-1);            mxmy[rp(px-py,sxmy,lxmy)].erase(i-1);            px=x[i];py=y[i];        }        printf("%d\n",ans);    }else printf("0\n");    return 0;}
0 0