P2994题解
理解题意:
我第一次看这道题的时候,没理解输入数据,所以在这里解释一下:
题目中的奶牛进入餐厅和座位的四个变量,两两一组是直角坐标系里的
那么问题又来了,到底先枚举奶牛还是座位。也就是两层循环哪一个放在外面 当然是先枚举座位,即外层循环是枚举座位,内层循环枚举奶牛。因为每一个奶牛不一定有座位,但是每一个座位一定有奶牛。
本题可以定义四个数组储存变量,但是这里可以优化一下,只定义两个数组,剩下两个直接定义成普通变量。因为座位可以每输入一个进行一次奶牛查找(判断哪一个奶牛)放在同一个 for 循环中,具体见下方代码:
代码示例:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+5;//为了方便定义数组,直接把数据范围控制好
long long a[maxn],b[maxn],c,d;//a,b表示奶牛计入房间位置,c,d表示座位位置
int flag[maxn];//用来标记那些奶牛已经有座位了
int pos;//记录有座位的奶牛编号
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i]>>b[i];
for(int j=1;j<=m;j++)
{
cin>>c>>d;
long long dis=0;//计算当前奶牛到座位的距离,用勾股定理(因为只需要比较,所以没有开根号)
long long mindis=1e15;//记录当前最小奶牛距桌子距离(开始随便赋值,大一些)
for(int i=1;i<=n;i++)
{
if(flag[i]==1)continue;//已有座位,直接跳过
dis=(a[i]-c)*(a[i]-c)+(b[i]-d)*(b[i]-d);//计算距离,用勾股定理
if(dis<mindis)//如果刷新了最小纪录
{
mindis=dis;//重新赋最小值
pos=i;//标记
}
}
flag[pos]=1;//标记,已有座位
}
if(n==m)//特判没有奶牛无座位
{
cout<<0;
return 0;
}
for(int i=1;i<=n;i++)//其他情况输出
{
if(flag[i])continue;
cout<<i<<endl;
}
return 0;
}