HDU 4311 Meeting point-1 && HDU 4312 Meeting point-2

这俩个题  题意::给出N(<1e5)个点求找到一个点作为聚会的地方,使每个点到达这里的距离最小。4311是 曼哈顿距离 4312是 切比雪夫距离;

曼哈顿距离 :大家都知道 对于二维坐标系a(xa,yb),b(xb,yb)的曼哈顿距离是abs(xa-xb)+abs(ya-yb);

  看的出来这个距离和x,y 都有关,但是X,Y并不相互影响,所以可以分开计算这样,分开计算的好处如下:

  如果 只给一个维度的坐标系 ,我们是不可以再什么养的复杂度的时间内处理出来呢? 大难还是很好想的先排序一下,会发现就需要O(n)的时间就可以算出来我们想要的答案

  至于俩个维度的合并运算只要O(N)记录就可以了;

切比雪夫距离:

  我们知道对于距离一个点的曼哈顿距离为R 的点可以形成一个正方形如下图:

  也知道对于距离一个点的切比雪夫距离为R 的点也可以形成一个正方形如下图:

   

  对比俩个图片我们知道:距离一个点的 切比雪夫距离可以通过一定的变换转换成 曼哈顿距离(因为曼哈顿距离怎么算我们上面已经讲过了)!!!;

  比较麻烦?:但其实很简单:我们知道上面的 切比雪夫的正方形 旋转45度 在变换一定的倍数会 和 曼哈顿的正方形重合!所以我饿们可以认为 切比雪夫距离是  曼哈顿距离旋转在放大的结果:反过来只要对坐标进行同样的旋转和放大就可以了;

代码如下:::

#include <cstdio>
#include <map>
#include <vector>
#include <set>
#include <iostream>
using namespace std;
typedef long long LL;
struct info
{
    LL x,y;
    int cnt;
    info(){}
    info(int x,int y):x(x),y(y){}
};
bool cmpx(info  a,info b)
{
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
bool cmpy(info a,info b)
{
    if(a.y==b.y) return a.x<b.x;
    return a.y<b.y;
}
info ko1[100005];
info ko2[100005];
LL dp1[100005];
LL dp2[100005];
int n;
void make(int x)
{
    int tmpx,tmpy;
    tmpx=ko1[x].x;
    tmpy=ko1[x].y;
//这么写是按远点点进行逆时针旋转的
//你也可以按别的点进行旋转  不过们的旋转点必须是一个
//列
//tmpx=ko1[x].x-2;
//tmpy=ko1[x].y+12;
    ko1[x].x=tmpx-tmpy;
    ko1[x].y=tmpy+tmpx;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
           // cin>>ko1[i].x>>ko1[i].y;
            scanf("%I64d%I64d",&ko1[i].x,&ko1[i].y);
            make(i);//有这句是12 没这句是11
        }
        sort(ko1+1,ko1+1+n,cmpx);
        for(int i=1;i<=n;i++)
        {
            ko1[i].cnt=i;
            ko2[i]=ko1[i];
        }
        sort(ko2+1,ko2+1+n,cmpy);
        for(int i=1;i<=n;i++)
        {
            dp1[i]=dp1[i-1]+abs(ko1[i].x-ko1[1].x);
            dp2[i]=dp2[i-1]+abs(ko2[i].y-ko2[1].y);
        }
        LL ans=1LL<<62;
        for(int i=1;i<=n;i++)
        {
            LL tmp2=dp2[n]-dp2[i]-(ko2[i].y-ko2[1].y)*(n-i)+(ko2[i].y-ko2[1].y)*i-dp2[i];
            int cnt=ko2[i].cnt;
            LL tmp1=dp1[n]-dp1[cnt]-(ko1[cnt].x-ko1[1].x)*(n-cnt)+(ko1[cnt].x-ko1[1].x)*cnt-dp1[cnt];
            ans=min(ans,(tmp1+tmp2)/2);//  这个12 要除以2;11不需要
        }
        cout<<ans<<endl;
    }
    return 0;
}

  

HDU 4311 Meeting point-1 && HDU 4312 Meeting point-2,布布扣,bubuko.com

时间: 2024-10-27 05:03:19

HDU 4311 Meeting point-1 && HDU 4312 Meeting point-2的相关文章

HDU 4311&amp;4312 Meeting point-1&amp;2 (曼哈顿距离&amp;&amp;切比雪夫距离)

HDU 4311 题意:平面上有n个点,一个点(x,y)只能到达(x-1,y), (x+1,y), (x, y-1), (x, y+1)4个点.从n个点中找到一点,使其他点到此点的距离之和最小. 思路: 可以发现,两个点间距离为 |x1-x2| + |y1-y2| ,这便是两点间的曼哈顿距离. 朴素的做法是遍历所有点,枚举该点与其他点间的曼哈顿距离之和,但是会TLE: 取巧的做法是将所有点与中心点的曼哈顿距离排序,枚举中间大概250个点左右的情况比较即可(不要欺负人家数据水! 正确姿势: 用结构

hdu 1171 Big Event in HDU(母函数|多重背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意:有n种物品,给出每种物品的价值和数目,要将这些物品尽可能的分成相等的两份A和B且A>=B ,输出A,B. 母函数可以过,但感觉最直接的方法应该是多重背包. 母函数的话,也是按总价值的一半求,从一半到小枚举,直到找到系数不为0的就是B. #include <stdio.h> #include <iostream> #include <map> #include <

hdu 1171 Big Event in HDU

Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22611    Accepted Submission(s): 7942 Problem Description Nowadays, we all know that Computer College is the biggest department

HDU 1171 Big Event in HDU --暴力+生成函数

题意:给n种房子,每种房子有一个值val和个数cnt,现在要把这些房子分成两部分,争取两部分总值相等,如果不能相等,让A>B,且A-B最小. 解法:先跑一次生成函数,c[n]表示组成总值为n的方法种数,然后从Total/2~0枚举B的总值,如果c[i]不为0,说明可以达到 i 这个状态,说明这就是B的最接近A的值(因为最接近Total/2).算法复杂度较高.跑了1600多ms,不知道还有没有更优的算法. 代码: #include <iostream> #include <cstdi

HDU - 1232 畅通工程 HDU - 1874畅通工程续 HDU - 1875畅通工程再续

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1232 题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1874 题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1875 畅通工程属于水题,直接用并查集就行,加个路径压缩那就更好. 畅通工程续这道题WA了N次,因为有一个地方没注意到就是一个城镇到另外一个城镇的有多条道路, 所以你一开始就要把最短的道路选出来.

hdu 1171 Big Event in HDU(母函数)

链接:hdu 1171 题意:这题可以理解为n种物品,每种物品的价值和数量已知,现要将总物品分为A,B两部分, 使得A,B的价值尽可能相等,且A>=B,求A,B的价值分别为多少 分析:这题可以用母函数的思想解,不过求的不是方案数,而是判断尽可能接近总价值的一半的方案是否存在. 也可以用背包思想,每种物品的价值和数量已知,可以将总价值的一半作为容量,求最大价值,也就最接近所求值了 注:数组要开的稍微大一点,否则可能WA #include<stdio.h> #include<strin

HDU 1171 Big Event in HDU (动规)

Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22623    Accepted Submission(s): 7948 Problem Description Nowadays, we all know that Computer College is the biggest department

HDU 1564 Play a game &amp;&amp; HDU 2147 kiki&#39;s game

HDU 1564 Play a game题意: 棋盘的大小是n*n.一块石头被放在一个角落的广场上.他们交替进行,8600人先走.每次,玩家可以将石头水平或垂直移动到一个未访问的邻居广场.谁不采取行动,谁就会输掉这场比赛.如果双方都打得很好,谁将赢得比赛? 题解: 三角形代表起始位置,虽然不是右上角但是解题都差不多 如果n为偶数,那么所有格子可以被2*1的砖块覆盖掉. 这样先手每次都移动到当前1*2的另外一块.先手必赢. 如果n为奇数.出了起始那个店,其余点都可以被覆盖. 代码: 1 #incl

HDU 4311,4312 Meeting point(曼哈顿距离,切比雪夫距离)

 题意: 面上n个点,某点到其他点的曼哈顿距离最小和,切比雪夫距离最小和. 思路:对于切比雪夫距离可以转化为哈密顿距离,方法是将每个点的坐标逆时针旋转45度然后放大sqrt(2)倍,换成坐标表示也就是(x,y)->(x-y,x+y). 对于第一个问题,求曼哈顿距离最小和,也就是sum(xj-xi)+sum(yj-yi). 如果直接求时间复杂度无法承受. 所以我们可以先对x排序,对于从左到右的sum(x)我们可以递推出来,即sumx[tj[i].id] = sumx[tj[i-1].id] +