地图查询
在他人基础上改的
#include<iostream>
#include<vector>
#include<map>
#include <cassert>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define EPS 1e-7
using namespace std;
double X,Y; //某个位置的坐标
struct MAP
{
string name;
double x1,x2,y1,y2,area,Ratio;
int level;
pair<double,double> center;
MAP(double _x1, double _y1, double _x2, double _y2, string _name):
x1(_x1), y1(_y1), x2(_x2), y2(_y2), name(_name){
if(x1 > x2)swap(x1,x2);
if(y1 > y2)swap(y1,y2);
area = (x2-x1)*(y2-y1);
Ratio = (y2 - y1) / (x2 - x1);
center.first = (x1+x2)/2.0;
center.second = (y1+y2)/2.0;
}
//根据题目要求列出各种判断条件
bool operator <(const MAP &m)const
{
if(level!=m.level) return level<m.level;
double d1=(center.first-X)*(center.first-X)+(center.second-Y)*(center.second-Y);
double d2=(m.center.first-X)*(m.center.first-X)+(m.center.second-Y)*(m.center.second-Y);
if(fabs(d1-d2)>EPS) return d1<d2;
d1=fabs(Ratio-0.75);
d2=fabs(m.Ratio-0.75);
if(fabs(d1-d2)>EPS) return d1<d2;
d1=(x2-X)*(x2-X)+(y2-Y)*(y2-Y);
d2=(m.x2-X)*(m.x2-X)+(m.y2-Y)*(m.y2-Y);
if(fabs(d1-d2)>EPS) return d1>d2;
return x1<m.x2;
}
};
vector<MAP>maps;//输入的地图
map<string,pair<double,double> > site;//储存地址名字和坐标
vector<double>area;//储存面积
vector<MAP>yes;//需要的符合的地图
int contain(string s)
{
int num=0;
double x=site[s].first,y=site[s].second;
for(int i=0;i<maps.size();i++)
{
if(x >= maps[i].x1 && x <= maps[i].x2 && y >= maps[i].y1 && y <= maps[i].y2)//找到符合的地图就将它存入容器 城市在这个地图里
{
num++;
yes.push_back(maps[i]);
area.push_back(maps[i].area);
}
}
return num;
}
int main()
{
string s;
cin>>s;
while(cin>>s&&s!="LOCATIONS")
{
double x1,x2,y1,y2;
cin>>x1>>y1>>x2>>y2;
maps.push_back(MAP(x1,y1,x2,y2,s));
}
while(cin>>s&&s!="REQUESTS")
{
double x,y;
cin>>x>>y;
site[s]=make_pair(x,y);
}
while(cin>>s&&s!="END")
{
int level;
cin>>level;
yes.clear();area.clear();
printf("%s at detail level %d ",s.c_str(),level);
if(!site.count(s)) printf("unknown location\n");//没有在城市中找到
else if(!contain(s)) printf("no map contains that location\n");
else
{
X=site[s].first;Y=site[s].second; //寻找的城市的坐标
sort(area.begin(),area.end(),greater<double>()); //进行降序排序,以下为unique用法
int N=area.size();
vector<double>::iterator new_end;
new_end=unique(area.begin(),area.end()); //"删除"相邻的重复元素
assert(area.size()==N);
area.erase(new_end,area.end()); //删除(真正的删除)重复的面积值
int num=area.size();
for(int i=0;i<yes.size();i++)
{
for(int j=0;j<num;j++)
{
if(yes[i].area==area[j]) {yes[i].level=j+1;break;}//对各个地图进行详细等级排序,找到它的等级
}
}
sort(yes.begin(),yes.end());//进行终极排序
if(num<level) printf("no map at that detail level; ");//如果面积数小于要求水平,则不存在
int temp=yes.size()-1;//最详细的地图下标
for(int i=0;i<yes.size();i++)
{
if(level==yes[i].level)//找到了,一定别忘了break!
{temp = i;break;}
}
cout << "using " << yes[temp].name << endl;//......我当时傻傻的把这里写成了yes[yes.size()-1],找了半天的错,,,宛如一个智障
}
}
}
下面是我借鉴的原码,其实有些地方我感觉他并不太对,对比一下吧,也有可能是我不懂【笑哭】
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define EPS 1e-7
using namespace std;
double X,Y; //某个位置的坐标
struct MAP
{
string name;
double x1,x2,y1,y2,area,Ratio,level;
pair<double,double>center;
MAP(double _x1, double _y1, double _x2, double _y2, string _name):
x1(_x1), y1(_y1), x2(_x2), y2(_y2), name(_name){
if(x1 > x2)swap(x1,x2);
if(y1 > y2)swap(y1,y2);
area = (x2-x1)*(y2-y1);
Ratio = (y2 - y1) / (x2 - x1);
center.first = (x1+x2)/2.0;
center.second = (y1+y2)/2.0;
}
bool operator <(const MAP &b) const
{
if(level != b.level) return level > b.level;
double d1 = (center.first-X)*(center.first-X) + (center.second-Y)*(center.second-Y);
double d2 = (b.center.first-X)*(b.center.first-X) + (b.center.second-Y)*(b.center.second-Y);
if(fabs(d1-d2) > EPS) return d1 < d2;
d1 = fabs(Ratio-0.75),d2 = fabs(b.Ratio-0.75);
if(fabs(d1-d2) > EPS) return d1 < d2;
d1 = (X-x2)*(X-x2)+(Y-y1)*(Y-y1);
d2 = (X-b.x2)*(X-b.x2)+(Y-b.y1)*(Y-b.y1);
if(fabs(d1-d2) > EPS) return d1 > d2;
return x1 < b.x1;
}
};
vector<MAP>maps;
map<string,pair<double,double> >site; //存储位置及其坐标
vector<int>cover; //包含点(X,Y)的地图下标
vector<double>area; //面积
vector<MAP>yes; //包含点(X,Y)的地图
int no_contain(string s) //判断有没有地图包含这个位置(X,Y)
{
double x = site[s].first, y = site[s].second;
int sum = 0;
for(int i = 0; i < maps.size(); i++)
if(x >= maps[i].x1 && x <= maps[i].x2 && y >= maps[i].y1 && y <= maps[i].y2)
sum++, cover.push_back(i);
return sum;
}
int main()
{
string s;
cin >> s;
while(cin >> s && s != "LOCATIONS"){
double x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
maps.push_back(MAP(x1,y1,x2,y2,s));
}
while (cin >> s, s != "REQUESTS"){
double x,y;
cin >> x >> y;
site[s] = make_pair(x,y);
}
while(cin >> s && s != "END"){
int level; cin >> level;
cover.clear();area.clear();yes.clear();
printf("%s at detail level %d ",s.c_str(),level);
if(!site.count(s)) {printf("unknown location\n");}
else if(!no_contain(s)) {printf("no map contains that location\n");}
else{
for(int i = 0; i < cover.size(); ++i)
{yes.push_back(maps[cover[i]]); area.push_back(maps[cover[i]].area);}//不是很懂为啥这样做
X = site[s].first, Y = site[s].second;
sort(area.begin(),area.end(),greater<double>());
unique(area.begin(),area.end()); //面积去重
int num = area.size(), temp = 0;
for(int i = 0; i < yes.size(); i++)
for(int j = 0; j < num; j++)
if(yes[i].area == area[j]) {yes[i].level = j+1;break;}
sort(yes.begin(),yes.end());
if(num < level) printf("no map at that detail level; ");//实验证明num 并不是去重后的新数,还是原来的带着重复的数值,num应是不同值的总数
for(int i = 0;i < yes.size();i++)if(level == yes[i].level) {temp = i;break;}
cout << "using " << yes[temp].name << endl;//不明白temp为何是用初值为0,按道理说应该是最后一个
}
}
}