UVALive-7222 National Disaster【思维+排序+模拟】

本文介绍了一个关于寻找最优距离参数p的问题解决方法。该问题涉及基于点的坐标计算距离,并通过比较实际可见性矩阵与报告中给出的可见性矩阵来确定最小错误数。文章提供了一种通过逐步增加距离阈值并跟踪最小错误数量的方法来解决问题的有效算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目大意:

给你N个点的坐标,两个人互相能够看到的限制是两个人处于的位子的距离小于等于p.此时给你一个01矩阵,表示报告上写的内容,其中Aij如果是1的话,表示i能够看到j.

现在已知报告会有一部分错误,让你找到一个值p,使得错误最少。如果p有多解,输出最小值。


思路:


最多一共有200个点,那么一共就有40000种距离,我们不妨将其按照从小到大排序,那么初始的时候如果我们选定p==0.那么结果矩阵就是全0的.

那么此时作为初始结果矩阵,我们每一次将一种距离放置矩阵中,使得这个位子从0变成1.

过程维护一下最小值即可。


Ac代码:


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long int
struct node
{
    ll x,y,diss;
}b[500*500];
ll x[5000];
ll y[5000];
ll dis[500][500];
ll temp[500][500];
ll a[500][500];
ll n,sum,cnt;
int cmp(node a,node b)
{
    return a.diss<b.diss;
}
void init()
{
    cnt=0;
    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<n;j++)
        {
            dis[i][j]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
            b[cnt].x=i;
            b[cnt].y=j;
            b[cnt].diss=dis[i][j];
            cnt++;
        }
    }
}
int main()
{
    ll t;
    ll kase=0;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&n);
        memset(temp,0,sizeof(temp));
        for(ll i=0;i<n;i++)scanf("%lld",&x[i]);
        for(ll i=0;i<n;i++)scanf("%lld",&y[i]);
        for(ll i=0;i<n;i++)
        {
            for(ll j=0;j<n;j++)
            {
                scanf("%lld",&a[i][j]);
            }
        }
        init();
        sort(b,b+cnt,cmp);
        ll output,output2;
        ll sum=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(temp[i][j]!=a[i][j])sum++;
            }
        }
        output2=sum,output=0;
        for(int i=0;i<cnt;i++)
        {
            temp[b[i].x][b[i].y]=1;
            if(a[b[i].x][b[i].y]==1)
            {
                sum--;
            }
            else
            {
                sum++;
            }
            if(i+1==cnt||b[i].diss!=b[i+1].diss)
            {
                if(sum<output2)
                {
                    output2=sum;
                    output=b[i].diss;
                }
                if(sum==output2)
                {
                    output2=sum;
                    output=min(output,b[i].diss);
                }
            }
        }
        printf("Case #%lld: ",++kase);
        printf("%lld %lld\n",output,output2);
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值