问题:在周赛中遇到这么一道题:
Description
TUstarry 跟他的女朋友去一个人气餐厅约会,不巧的是他的前女友也在门口排队。DOGGOD_Q 是这个餐厅的服务生,负责为客人安排座位。他知道这个餐厅还有 n 个空位,并清楚这些座位的位置,他想把 TUstarry 和他的前女友安排的稍微远一点,但是又觉得直接安排到相距最远的座位会显得有些刻意,所以他打算把他们安排在距离第二远的一对座位上,可惜这不是他能直接看出来的,所以他找到你来帮忙。
Input
第一行为一个整数 t (1 <= t <= 1e4) 代表有 t 组数据
在每组数据中,第一行为一个正整数 n (1 <= n <= 1e5),接下来 n 行每行有一对整数 xi, yi,代表第 i 个座位的坐标 (xi, yi).(0 <= |x|,|y| <= 1e4)
输入数据保证所有 n 的和小于 2e5,保证两个座位不会重叠。两个座位的距离即两个坐标在平面直角坐标系上的欧几里得距离
Output
每个输入数据对应一行输出,为一个整数,表示距离第二远的这对椅子距离的平方值
Sample Input
2
4
1 1
2 3
5 3
5 1
5
1 1
1 2
3 4
1 6
4 5Sample Output
16
25
然鹅比赛结束了AC还是0,求解qwq
//更新:赛后写了个满足测试用例的(边缘数据不知道能不能过)
#include<stdio.h>
#include<math.h>
int distance(int a,int b);
int main()
{
int group,num,t;
int position1[50],position2[50],dis[50];
scanf("%d",&group);
for(int i=1;i<=group;i++)
{
for(int j=0;j<50;j++) //数组初始化
{
position1[j]=0;
position2[j]=0;
dis[j]=0;
}
scanf("%d",&num);
for(int j=0;j<num;j++)
{
scanf("%d %d",&position1[j],&position2[j]);
dis[j]=distance(position1[j],position2[j]);
//printf("%d",dis[j]);
}
//排序
for(int k=0;k<num-1;k++)
{
for (int j=0;j<num-1;j++)
if(dis[j]>dis[j+1]) //如果前一个数比后一个数大,则利用中间变量t实现两值互换
{
t=dis[j]; //距离互换的同时值也互换
dis[j]=dis[j+1];
dis[j+1]=t;
t=position1[j];
position1[j]=position1[j+1];
position1[j+1]=t;
t=position2[j];
position2[j]=position2[j+1];
position2[j+1]=t;
}
}
int ans=pow((position1[num-2]-position1[0]),2)+pow((position2[num-2]-position2[0]),2);
printf("%d\n",ans);
}
}
int distance(int a,int b)
{
return a*a+b*b;
}
显然,上述题目的核心涉及输出第二远的距离,在此需要使用排序方法。
(因为之前只简单了解了几种排序算法名称,并不知道具体的实现方案 ,比赛结束后特来学习)
本篇从最简单的两种算法开始:冒泡排序与选择排序
一、选择排序
原理:对数据进行多次遍历,每次遍历(第n次)都选出该次遍历数据最大(或最小)数据放于数组第n位。直到遍历结束数据由小到大(或由大到小)排列。
原理图(来源网络)
核心:找一轮数据最值,放于特定位置
代码实现:(自己根据原理写的,可能有优化空间)
#include <stdio.h> //以选择由小到大为例
int main()
{
int num,choice[50],t;
printf("请输入需要排序数据的组数:");
scanf("%d",&num); //输入数据的组数
for(int i=0;i<num;i++)
{
scanf("%d",&choice[i]); //读入数据
}
//先假设第一个数据为最小的
for(int i=0;i<num-1;i++)
{
for(int j=i+1;j<num;j++)
{
if(choice[i]>choice[j])
{
t=choice[i]; //一轮遍历找出最小的一个
choice[i]=choice[j];
choice[j]=t;
}
}
}
for(int i=0;i<num;i++)
{
printf("%d ",choice[i]);
}
}
二、冒泡排序
原理:对数据进行多轮遍历,每轮对两组数据进行两两比较,按需求(升序或者降序)判断是否需要交换顺序。
核心:两两比较,看是否交换位置
代码实现:
#include <stdio.h> //以冒泡由小到大为例
int main()
{
int num,bub[50],t;
printf("请输入需要排序数据的组数:");
scanf("%d",&num); //输入数据的组数
for(int i=0;i<num;i++)
{
scanf("%d",&bub[i]); //读入数据
}
for(int i=0;i<num-1;i++)
{
for(int j=0;j<num-1;j++)
{
if(bub[j]>bub[j+1])
{
t=bub[j];
bub[j]=bub[j+1];
bub[j+1]=t;
}
}
}
for(int i=0;i<num;i++)
{
printf("%d ",bub[i]);
}
}
个人更看好简单明了的选择排序~毕竟最简单的排序方法谁不爱呢0w0