UVA 1388 - Graveyard

题意:n个点在一个圆上,每个点的距离平均分布,再加入M个点,那么最少需要移动多少距离可以让n+m个点平均分布,问最少移动的距离、

思路:模拟,将N个点的位置求出来,再将n+m个点的位置求出来,第一个点都是固定不动的,其他的点只需要按照最短的移动便可、

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110000;
int n,m;
double ans;
struct node{
    double x;
    int y;
    int z;
}msq[maxn];
int cmd(struct node a,struct node b){
    return a.x<b.x;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF){
        if(n==m){
            printf("0.0\n");
            continue;
        }
        ans=0.0;
        msq[0].x=0.0;msq[0].y=1;msq[0].z=1;
        msq[2*n+m-1].x=0.0;msq[2*n+m-1].y=1;msq[2*n+m-1].z=1;
            for(int i=1;i<n;i++){
                msq[i].x=(10000.0/(n*1.0))*(i*1.0);
                msq[i].y=1;
                msq[i].z=0;
            }
            for(int i=n;i<2*n+m-1;i++){
                msq[i].x=(10000/((m+n)*1.0))*((i-n+1)*1.0);
                msq[i].y=2;
                msq[i].z=0;
            }
            sort(msq,msq+n+m+n-1,cmd);
            for(int i=1;i<m+n+n-1;i++){
                if(msq[i].y==1&&msq[i].x==msq[i-1].x){
                    msq[i-1].y=1;
                    continue;
                }
                else if(msq[i].y==1&&msq[i].x==msq[i+1].x){
                    msq[i+1].y=1;
                    continue;
                }
                else if(msq[i].y==1){
                    if(msq[i-1].y==2&&msq[i+1].y==2){
                        if(msq[i-1].z==0&&msq[i-1].z==0){
                            if(msq[i].x-msq[i-1].x>msq[i+1].x-msq[i].x){
                                ans+=msq[i+1].x-msq[i].x;
                                msq[i+1].z=1;
                            }
                            else{
                                ans+=msq[i].x-msq[i-1].x;
                                msq[i].z=1;
                            }
                        }
                        else if(msq[i-1].z==0){
                            msq[i-1].z=1;
                            ans+=msq[i].x-msq[i-1].x;
                        }
                        else if(msq[i+1].z==0){
                            msq[i+1].z=1;
                            ans+=msq[i+1].x-msq[i].x;
                        }
                }
                else if(msq[i-1].y==2&&msq[i-1].z==0){
                    ans+=msq[i].x-msq[i-1].x;
                    msq[i-1].z=1;
                }
                else if(msq[i+1].y==2&&msq[i-1].z==0){
                    ans+=msq[i+1].x-msq[i].x;
                    msq[i+1].z=1;
                }
            }
        }
    if(10000%n==0&&10000%(n+m)==0)
        printf("%.1lf\n",ans);
    else
        printf("%.4lf\n",ans);
}
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值