货仓选址
题目描述:
在一条数轴上有 N 家商店,它们的坐标分别为 A1~AN。现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数N。第二行N个整数A1~AN。
输出格式
输出一个整数,表示距离之和的最小值。
数据范围
1≤N≤100000
输入样例:
4
6 2 9 1
输出样例:
12
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int a[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
int sum=0;
for(int i=1;i<=n/2;i++){
sum+=a[n-i+1]-a[i];
}
cout<<sum<<endl;
}
股票买卖 II
股票买卖 II
题意
给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
输入格式
第一行包含整数 N,表示数组长度。
第二行包含 N 个不大于 10000 的正整数,表示完整的数组。
输出格式
输出一个整数,表示最大利润。
数据范围
1≤N≤105
输入样例1:
6
7 1 5 3 6 4
输出样例1:
7
输入样例2:
5
1 2 3 4 5
输出样例2:
4
输入样例3:
5
7 6 4 3 1
输出样例3:
0
样例解释
样例1:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。共得利润 4+3 = 7。
样例2:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
样例3:在这种情况下, 不进行任何交易, 所以最大利润为 0。
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int main(){
int n,ans=0;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=1;i<n;i++){
if(a[i]>a[i-1]){
ans+=a[i]-a[i-1];
}
}
cout<<ans;
return 0;
}
糖果传递
有 n 个小朋友坐成一圈,每人有 a[i] 个糖果。
每人只能给左右两人传递糖果。
每人每次传递一个糖果代价为 1。
求使所有人获得均等糖果的最小代价。
输入格式
第一行输入一个正整数 n,表示小朋友的个数。
接下来 n 行,每行一个整数 a[i],表示第 i 个小朋友初始得到的糖果的颗数。
输出格式
输出一个整数,表示最小代价。
数据范围
1≤n≤1000000,
0≤a[i]≤2×109,
数据保证一定有解。
输入样例:
4
1
2
5
4
输出样例:
4
我们设 xi为第i个人分给第i-1个人的糖果数,可正可负,用方程表示后
我们求解的答案|x1|+|x2|+|x3|+..... +|xn|
的最小值
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
typedef long long LL;
long long a[N],c[N];
int main(){
int n;
cin>>n;
LL sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
sum=sum/n;
c[n]=sum-a[n];
for(int i=n-1;i>=2;i--){
c[i]=c[i+1]+sum-a[i];
}
c[1]=0;
sort(c+1,c+n+1);
LL ans=0;
for(int i=1;i<=n/2;i++){
ans+=(LL)(c[n-i+1]-c[i]);
}
cout<<ans;
return 0;
}
112. 雷达设备
1.题目
假设海岸是一条无限长的直线,陆地位于海岸的一侧,海洋位于另外一侧。
每个小岛都位于海洋一侧的某个点上。
雷达装置均位于海岸线上,且雷达的监测范围为 d,当小岛与某雷达的距离不超过 d时,该小岛可以被雷达覆盖。
我们使用笛卡尔坐标系,定义海岸线为 x 轴,海的一侧在 x轴上方,陆地一侧在 x 轴下方。
现在给出每个小岛的具体坐标以及雷达的检测范围,请你求出能够使所有小岛都被雷达覆盖所需的最小雷达数目。
输入格式
第一行输入两个整数 n和 d,分别代表小岛数目和雷达检测范围。
接下来 n 行,每行输入两个整数,分别代表小岛的 x,y轴坐标。
同一行数据之间用空格隔开。
输出格式
输出一个整数,代表所需的最小雷达数目,若没有解决方案则所需数目输出 −1。
数据范围
1 ≤ n ≤ 1000 1≤n≤10001≤n≤1000,
− 1000 ≤ x , y ≤ 1000 −1000≤x,y≤1000−1000≤x,y≤1000
输入样例:
3 2
1 2
-3 1
2 1
输出样例:
2
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1010;
struct segment{
double l,r;
bool operator<(const segment& t ){
return r<t.r;
}
}seg[N];
int main(){
int n,d;
cin>>n>>d;
bool failed=false;
for(int i=0;i<n;i++){
int x,y;
float dx;
cin>>x>>y;
if(y>d){
failed=true;
}
else{
dx=sqrt(pow(d,2)-pow(y,2));
seg[i].l=x-dx;
seg[i].r=x+dx;}
}
if(failed==true){
puts("-1");
}
else{
sort(seg,seg+n);
int ans=0;
float last=-1e20;
for(int i=0;i<n;i++){
if(seg[i].l>last){
ans++;
last=seg[i].r;
}
}
cout<<ans<<endl;
}
}
几个人一起出去吃饭是常有的事。但在结帐的时候,常常会出现一些争执。
现在有 n 个人出去吃饭,他们总共消费了 S 元。
其中第 i 个人带了ai 元。
幸运的是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?
为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标准差最小。
这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是1分钱的整数倍。你需要输出最小的标准差是多少。
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=500010;
int a[N];
int main(){
int n;
long double s;
scanf("%d %llf",&n,&s);
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
long double ave=s/n;
long double res=0;
for(int i=0;i<n;i++){
double cur=s/(n-i);
if(a[i]<cur)cur=a[i];
res+=(cur-ave)*(cur-ave);
s-=cur;
}
printf("%.4llf",sqrt(res/n));
}
1239. 乘积最大
给定 N 个整数 A1,A2,…AN。
请你从中选出 K 个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009 的余数。
注意,如果 X<0, 我们定义 X 除以 1000000009 的余数是负(−X)除以 1000000009 的余数,即:0−((0−x)%1000000009)
分情况讨论
当k=n;全部取
k<n;k为偶数时,取绝对值最大的偶个负数与偶个整数;负数选择时成对地选
k为奇数时,特殊情况如果全是负数,选择最大的k个负数
至少存在一个非负数,那么选择这个最大的数,然后从n-1个数选择 k-1(偶数)个数,转化为情况一
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+10,mod=1000000009;
int a[N];
int main(){
int n,k;
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
int l=0,r=n-1;
int sign=1;
LL res=1;
if(k%2){
res=a[r--];
k--;
if(res<0){
sign=-1;
}
}
while(k){
LL x=(LL)a[l]*a[l+1];
LL y=(LL)a[r]*a[r-1];
if(x*sign>y*sign){
res=x%mod*res%mod;
l+=2;
}
else{
res=y%mod*res%mod;
r-=2;
}
k=k-2;
}
printf("%d",res);
}
题目描述
给定N 个加号、M 个减号以及N + M + 1 个整数A1,A2,…,AN+M+1
小明想知道在所有由这N 个加号、M 个减号以及N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用1 2 3 + -,则“2 3 + 1 -” 这个后缀表达式结果是4,是最大的。
输入
第一行包含两个整数N 和M。
第二行包含N + M + 1 个整数A1,A2,…,AN+M+1
0<=N,M<=100000,-109<=Ai<=109
输出
输出一个整数,代表答案。
样例输入
1 1
1 2 3
1
2
样例输出
4
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=2e5+10;
int a[N];
int main(){
int n,m;
LL sum=0;
scanf("%d %d",&n,&m);
int k=m+n+1;
for(int i=0;i<k;i++){
scanf("%d",&a[i]);
}
if(!m){
for(int i=0;i<k;i++)
sum+=a[i];
}
else{
sort(a,a+k);
sum=a[k-1]-a[0];
for(int i=1;i<=k-2;i++){
sum+=abs(a[i]);
}}
cout<<sum;
}
灵能传输
问题描述
你控制着 n 名高阶圣堂武士,方便起见标为 1,2,··· ,n。每名高阶圣堂武士
需要一定的灵能来战斗,每个人有一个灵能值 a i 表示其拥有的灵能的多少(a i
非负表示这名高阶圣堂武士比在最佳状态下多余了 a i 点灵能,a i 为负则表示这
名高阶圣堂武士还需要 −a i 点灵能才能到达最佳战斗状态) 。现在系统赋予了
你的高阶圣堂武士一个能力,传递灵能,每次你可以选择一个 i ∈ [2,n − 1],若
a i ≥ 0 则其两旁的高阶圣堂武士,也就是 i − 1、i + 1 这两名高阶圣堂武士会从
i 这名高阶圣堂武士这里各抽取 a i 点灵能;若 a i < 0 则其两旁的高阶圣堂武士,
也就是 i−1,i+1 这两名高阶圣堂武士会给 i 这名高阶圣堂武士 −a i 点灵能。形
式化来讲就是 a i−1 + = a i ,a i+1 + = a i ,a i − = 2a i 。
灵能是非常高效的作战工具,同时也非常危险且不稳定,一位高阶圣堂
武士拥有的灵能过多或者过少都不好,定义一组高阶圣堂武士的不稳定度为
max n
i=1 |a i |,请你通过不限次数的传递灵能操作使得你控制的这一组高阶圣堂武
士的不稳定度最小。
输入描述
本题包含多组询问。
输入的第一行包含一个正整数 TTT 表示询问组数。 接下来依次输入每一组询问。
每组询问的第一行包含一个正整数 nnn,表示高阶圣堂武士的数量。
接下来一行包含 nnn 个数 a1,a2,⋅⋅⋅,ana_1,a_2,··· ,a_na1,a2,⋅⋅⋅,an。
其中,T≤3,3≤n≤300000,∣ai∣≤109T \leq 3,3 \leq n \leq 300000,|ai| \leq 10^9T≤3,3≤n≤300000,∣ai∣≤109.
输出描述
输出 TTT 行。每行一个整数依次表示每组询问的答案。
输入输出样例
示例
输入
3
3
5 -2 3
4
0 0 0 0
3
1 2 3
输出
3
0
3
运行限制
最大运行时间:1s
最大运行内存: 256M