UVA ~ 511 ~ Do You Know the Way to San Jose? (STL + 模拟)

题意:有n张地图(己知名称和某两个对角线端点的坐标) 和m个地名己知名称和坐标,还有q个查询、每张地图都是边平行于坐标轴的矩形,比例定义为高度除以宽度的值。每个查询包含一个地名name和详细等级level,面积相同的地图总是属于同一个详细等级,假定包含此地名的地图中一共有k种不同的面积,则合法的详细等级为1-k (其中1最不详细,k最详细,面积越小越详细)。如果详细等级level的地图不止一张,则输出地图中心和查询地名最接近的一张;如果还有并列的,地图长宽比应尽量接近0.75 (这是Web浏览器的比例);如果还有并列,查询地名和地图右下角的坐标应最远(对应最少的滚动条移动);如果还有并列,则输出x坐标最小的一个。如果查询的地名不存在或者没有地图包含它,或者包含它的地图总数超过i,应报告查询非法(并输出包含它的最详细地图名称,如果存在)。输出格式:

1.该城市不存在,输出“name at detail level level unknown location”

2.如果存在输出:“name at detail level level

①如果没有地图包含该位置输出“no map contains that location”

②如果有地图包含该位置,但是没有对应详细等级level的地图,输出最满足要求的地图名称“no map at that detail level; using MapName

③有该详细等级的地图包含该城市输出应该使用的地图名字,“using MapName


思路:用一个结构体存地图,存的时候调用构造函数,使x1<x2,y1<y2,(x1,y1)为左下角坐标,(x2,y2)为右上角

标,并把中心点和长宽比算出来。结构体自带一个查询一个点是否在里面的函数。

然后输入这些城市所在位置用map<string, pair<double, double> >存储,name对应坐标。

对于每次查询,如果不存在该城市,按要求输出。

 如果存在该城市,我们把所有包含该城市的地图存到vector<Map>C1中,按要求排序,然后我们再把C1中详细级别符合要求的存入C2,如果C1为空证明没有包含该城市的地图,如果C2为空证明没有详细级别符合要求的地图。

参考别人代码写的,所以基本跟人家写的一样,侵删。。。

#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-7;
struct Map
{
    string name;
    double x1, x2, y1, y2, area, Ratio;// Ratio长宽比
    pair<double, double> center;//中心坐标
    int level = -1;
    Map (string _name, double _x1, double _y1, double _x2, double _y2):
        name(_name), x1(_x1), y1(_y1), x2(_x2), y2(_y2)
    {
        if (x1 > x2) swap(x1, x2);
        if (y1 > y2) swap(y1, y2);
        area = (x2 - x1) * (y2 - y1);
        center.first = (x1 + x2) / 2.0; center.second = (y1 + y2) / 2.0;
        Ratio = (y2 - y1) / (x2 - x1);
    }
    bool contain(pair<double, double> pos) const //是否包含pos坐标
    {
        return pos.first >= x1 && pos.first <= x2 && pos.second >= y1 && pos.second <= y2;
    }
};
vector<Map> maps;//地图
map<string, pair<double, double> > site;//地点
pair<double, double> Qpos;
double dist(pair<double, double> A, pair<double, double> B)
{//hypot 对于给定的直角三角形的两个直角边,求其斜边的长度。
    return hypot(A.first - B.first, A.second - B.second);
}
bool cmp(const Map A, const Map B)
{
    //最详细
    if (A.area != B.area) return A.area < B.area;
    //地图中心和查询地名距离最近
    double d1 = dist(Qpos, A.center), d2 = dist(Qpos, B.center);
    if (fabs(d1 - d2) > EPS) return d1 < d2;
    //地图长宽比尽量接近0.75
    d1 = fabs(A.Ratio - 0.75), d2 = fabs(B.Ratio - 0.75);
    if (fabs(d1 - d2) > EPS) return d1 < d2;
    //查询地名和地图右下角坐标距离最远
    d1 = dist(Qpos, make_pair(A.x2, A.y1)), d2 = dist(Qpos, make_pair(B.x2, B.y1));
    if (fabs(d1 - d2) > EPS) return d1 > d2;
    //x坐标最小
    return A.x1 < B.x1;
}
int main()
{
    string name;
    cin >> name;
    while (cin >> name && name != "LOCATIONS")
    {
        double x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
        maps.push_back(Map(name, x1, y1, x2, y2));
    }
    while (cin >> name && name != "REQUESTS")
    {
        double x, y; cin >> x >> y;
        site[name] = make_pair(x, y);
    }
    while (cin >> name && name != "END")
    {
        int level; cin >> level;
        if (!site.count(name))//不存在
            printf("%s at detail level %d unknown location\n", name.c_str(), level);
        else
        {
            printf("%s at detail level %d ", name.c_str(), level);
            Qpos = site[name];
            vector<double> all_area;
            vector<Map> C1, C2;
            for (auto i: maps) if (i.contain(Qpos))
            {
                C1.push_back(i);
                all_area.push_back(i.area);
            }
            sort(all_area.begin(), all_area.end(), greater<double>());
            unique(all_area.begin(), all_area.end(), greater<double>());
            for (auto &i: C1)
                i.level = find_if(all_area.begin(), all_area.end(),
                          [i](const double area){ return fabs(area - i.area) <= EPS; }
                          ) - all_area.begin() + 1;

            sort(C1.begin(), C1.end(), cmp);
            copy_if(C1.begin(), C1.end(), back_inserter(C2),
                    [level](const Map& x) { return x.level == level; } );

            if (C1.size() == 0)
                puts("no map contains that location");
            else if (C2.size() == 0)
                printf("no map at that detail level; using %s\n", C1[0].name.c_str());
            else
                printf("using %s\n", C2[0].name.c_str());
        }
    }
    return 0;
}
/*
MAPS
BayArea -6.0 12.0 -11.0 5.0
SantaClara 4.0 9.0 -3.5 2.5
SanJoseRegion -3.0 10.0 11.0 3.0
CenterCoast -5.0 11.0 1.0 -8.0
SanMateo -5.5 4.0 -12.5 9.0
NCalif -13.0 -7.0 13.0 15.0
LOCATIONS
Monterey -4.0 2.0
SanJose -1.0 7.5
Fresno 7.0 0.1
SanFrancisco -10.0 8.6
SantaCruz -4.0 2.0
SanDiego 13.8 -19.3
REQUESTS
SanJose 3
SanFrancisco 2
Fresno 2
Stockton 1
SanDiego 2
SanJose 4
SantaCruz 3
END
*/



猜你喜欢

转载自blog.csdn.net/zscdst/article/details/80050441