题意:有n个点,找到一个顺序走遍这n个点,并且曼哈顿距离不超过25e8。
由于给的点坐标都在0-1e6之间。将x轴分成1000*1000,即1000长度为1块。将落在同一块的按y排序,编号为奇的块和偶的块一个升序,一个降序。有3个量值得关注。一是同一块中x的变化量,其实是不超过1000*n1,n1是第1块中点的数量。那么1000*n1+1000*n2......=1000*n<1e9。后两个量是同一块中y的高度差,另一个是本块最后一个和另一块第一个的高度差。这种做法下相邻两块这两个高度差的和是小于1.5e6的。1000块小于1.5e9。1e9+1.5e9刚好25e8。为什么高度差的和小于1.5e6?假设第k块是降序,Y的高度差是1e6,那么最低的一个点高度是0。如果它与下一块的第一个点的距离大于0.5e6,下一块所有点都要集中在上半部分,从而下一块的内部高度差就小于1e6。事实上,本块的最后一个点与下一块的第一个点的距离的增加必然导致下一块内部的高度差减小。
//#pragma comment(linker,"/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include <stack> #include <list> using namespace std; const int SZ=1000010,INF=0x7FFFFFFF; typedef long long lon; const double EPS=1e-9; struct nd{ int x,y,id; nd(int a,int b,int _id):x(a),y(b),id(_id){} }; vector<nd> vct[1010]; bool cmp1(nd &x,nd &y) { return x.y>y.y; } bool cmp2(nd &x,nd &y) { return x.y<y.y; } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int n; cin>>n; for(int i=0;i<n;++i) { int a,b; cin>>a>>b; int block=a/1000; vct[block].push_back(nd(a,b,i)); } for(int i=0;i<1010;++i) { if(i&1) { sort(vct[i].begin(),vct[i].end(),cmp2); } else { sort(vct[i].begin(),vct[i].end(),cmp1); } } bool ok=0; for(int i=0;i<1010;++i) { for(int j=0;j<vct[i].size();++j) { if(ok)cout<<" "; cout<<vct[i][j].id+1; ok=1; } } return 0; }
原文地址:https://www.cnblogs.com/gaudar/p/9671348.html
时间: 2024-10-05 22:18:32