前言
今天还是按照基础知识和刷题两个方向进行的学习。
一、基础知识
时间复杂度
二、题
1.Ants
n只蚂蚁以每秒1cm的速度在长为Lcm的竿子上爬行。当蚂蚁爬到竿子的端点时就会掉落。由于竿子太细,两只蚂蚁相遇时,它们不能交错通过,只能各自反向爬回去。对于每只蚂蚁,我们知道它距离竿子左端的距离x;,但不知道它当前的朝向。请计算所有蚂蚁落下竿子所需的最短时间和最长时间。
思路:
*(1)最短时间:*所有的蚂蚁都朝着离端点最近的方向走。由于蚂蚁的速度都相同,假如我们站在杆的中间看,它们在这种情况下是不会相遇的。
*(2)最长时间:*考虑最长时间,与最短时间相对的,蚂蚁都朝离端点远的方向走。我们就不得不思考蚂蚁相遇后的折返问题。我们想象一下两只蚂蚁A、B相遇了,依照题意,它俩相遇后将会各自按反方向走。事实上相遇后,A将走完B相遇前剩下的路,而B也将走完A在相遇前剩下的路。我们关注问题的焦点在与它们走到端点的时间,而速度一定,也就是说我们关注的是路程,而不是具体到某只蚂蚁怎样走。因此,A、B相遇后,各自折返走到端点的时间是和它们擦肩而过(还是照原来的方向走)的时间是一样的。
代码如下:
//输入
int L,n;
int x[MAX_N]
void solve(){
//计算最短时间
int minT=0;
for(int i=0;i<n;i++){
minT=max(minT,min(x[i],L-x[i]));
}
//计算最长时间
int maxT=0;
for(int i=0;i<n;i++){
maxT=max(maxT,maxT(x[i],L-minTx[i]));
}
printf("%d %d\n",minT,maxT);
}
2.cf
C. Lunar New Year and Number Division
(https://codeforces.com/problemset/problem/1106/C)
题目大意:求各组平方和的最小值。
思路:
给定n个数,将各个数利用sort()函数进行排序,将首位两个元素配对,形成一组,依次向中间的方向配对。
分析:
首先可以确定的是两两组合要比两个以上组合要小。在此基础上,我们把每组和的平方拆开看就是每个数的平方再加上两数之积的二倍。因此我们关注如何使两数之积的总和最小即可。如果转换成几何问题的话,就是说要使最后得到得面积最小。众所周知,周长一定的话长方形的面积是要比正方形的面积要小的。也就是说我们在构成长方形时,要使这个矩形的长和宽相差越夸张越好。因此可以转换为队列排序,首位组合。
代码如下:
#include<bits/stdc++.h>
using namespace std;
long long n,a[1000005];
long long sum=0;
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
for(int i=0;i<n;i++){
sum+=(a[i]+a[n-1-i])*(a[i]+a[n-1-i]);
}
cout<<sum/2<<endl;
return 0;
}
总结
今天做题感受到一个巧妙之处就是学会将问题进行转换,换个角度思考或许就会将问题简化很多。