Codeforces Gym 100341I Hungry Queen 2 Set+模拟
2015-09-06 10:32
393 查看
题目大意:
在一个无穷大的棋盘上有一个皇后在(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; }
相关文章推荐
- Codeforces Round #247 (D. Random Task)
- cf840A Leha and function
- UISnapBehavior-动画效果:迅猛移动弹跳摆动
- 事件传递和UIResponder
- Android 更新UI的两种方法——handler和runOnUiThread()
- Building Block(并查集)
- UISegmentedControl + UISlider +UIImageView的动画效果
- 去掉UItableview headerview黏性
- ue32编辑器光标怎么变成方的了,不方便啊,怎么改呢?
- 用requests和beautifulsoup爬取豆瓣电影top250,代码及遇到的问题
- iOS 小经验:UIAnimation空对象导致crash
- mysql prepareStatement executeQuery() 内存溢出的解决办法
- Maximum Subsequence Sum【最大连续子序列+树状数组解决】
- Build Systems to Be Zuhanden
- SequenceInputStream(序列流)
- UIViewAnimationOptions类型
- N-Queens II
- DB 查询分析器 6.04 在 Windows 10 上的安装与运行展示
- 用UIKIT的模态对话框要注意的地方
- 基于requests实现极客学院课程爬虫