126. 最大的和
简而言之就是求具有最大和的子矩形,并输出其最大和
解法参考文章链接https://www.acwing.com/solution/content/4127/
分析过程如下:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int g[105][105];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>g[i][j];
g[i][j]+=g[i-1][j];
}
int ans=-9999999;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
int tmp=0;
for(int k=1;k<=n;k++)
{
tmp=max(tmp,0)+g[j][k]-g[i-1][k];
ans=max(ans,tmp);
}
}
cout<<ans;
return 0;
}
/*
输入:
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
*/
443. 导弹拦截
输入样例:
0 0 6 0
5
-4 -2
-2 3
4 0
6 -2
9 1
输出样例:
30
解法参考文章链接https://www.acwing.com/solution/content/3596/
先用第一个雷达包围所有点,然后不断缩小第一个雷达的半径,每次圆边缘的点会从圈内出来,我们用第二个雷达去包含它即可。
枚举半径的方法:先将所有点按到第一个雷达的距离从大到小排序,依次枚举所有点所在的圆的半径即可。此时(a1,b1)的拦截半径为该点到第一个点的距离。
用第二个雷达去包含新点的方法:将最远的点退出,如果新点到第二个雷达的距离大于当前半径长度,则将半径更新成新的距离。若使用价值更小了则更新为point[i].d+r。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int n;
int a1,b1,a2,b2;//拦截系统坐标
struct Point
{
int x,y;
int d;//该点到(a1,b1)的距离
//按照距离从小到大排序
bool operator < (const Point &W)const
{
return d<W.d;
}
}point[N];
int distance(int x1,int y1,int x2,int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int main()
{
cin>>a1>>b1>>a2>>b2;
cin>>n;
//求所有导弹到(a1,b1)的距离
for(int i=0;i<n;i++)
{
int x,y;
cin>>x>>y;
point[i]={x,y,distance(x,y,a1,b1)};
}
//按照距离排序
sort(point,point+n);
reverse(point,point+n);//变成从大到小
int ans=point[0].d,r=0;
//减少拦截系统1的半径(每次以与导弹的距离为跨度)
for(int i=1;i<=n;i++)
{
//r为(a2,b2)的拦截半径
r=max(r,distance(point[i-1].x,point[i-1].y,a2,b2));
ans=min(ans,point[i].d+r);
}
cout<<ans;
return 0;
}
/*
输入:
0 0 6 0
5
-4 -2
-2 3
4 0
6 -2
9 1
*/
总时间复杂度是 O(nlogn)O(nlogn)。
琐碎知识点:
(1)结构体内嵌函数:https://blog.csdn.net/Nefeertari/article/details/113044058,其中涉及到const、重载操作符的知识
(2)const使用的全面总结:https://blog.csdn.net/Eric_Jo/article/details/4138548
(3)重载操作符(operator):https://blog.csdn.net/liitdar/article/details/80654324