大神排队--输油管道问题--士兵站队-
(2018-09-17 11:21:51)分类: 排序 |
一)395.大神排队(贪心排序)
现在共有n个同学要排成一列,每个同学有两个属性:影响力和承受能力。给一个同学造成的心理创伤指数,等于所有在他前面同学的影响力之和,减去他的承受能力。
请安排一下排队顺序,尽量使受到心理创伤最大的同学少受创伤。
输入格式:
第1行是整数n,表示同学人数
第2~n+1行,每行两个自然数,分别是该同学的影响力和承受能力。
输出格式:
输出1行1个整数,为你安排的顺序中受到心理创伤最大的同学受到的创伤
输入样例:
3
10 3
2 5
3 3
输出样例:
2
问题分析:
排序,关键确定逆序条件。
用冒泡去理解,假如前面已经完全排序完毕,第i,j两个人的排序比较是:
sum+a[j]-b[i] vs sum+a[i]-b[j];
a[i]+b[i] vs a[j]+b[j]
两值相等的话,谁的魅力a[i]小排前面
#include "bits/stdc++.h"
using namespace std;
int n;
struct demo{
int
x,y;
}
s[50050];
bool cmp(demo x,demo y)
{
if(x.x+x.y
< y.x+y.y) return 1;
if(x.x+x.y
> y.x+y.y) return 0;
if(x.x <
y.x) return 1;
return
0;
}
int main()
{
cin>>n;
for(int
i=1;i<=n;i++)
{
int
x,y;cin>>x>>y;
s[i].x=x;s[i].y=y;
}
sort(s+1,s+n+1,cmp);
int
tot=0,ans=-2100000;
for(int
i=1;i<=n;i++)
{
ans=max(ans,tot-s[i].y);
tot
+=s[i].x;
}
cout<<ans<<endl;
return
0;
}
二)ss2303输油管道问题
某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n 口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。如果给定n口油井的位置,即它们的x 坐标(东西向)和y 坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置? 证明可规定时间内确定主管道的最优位置。
编程任务:
给定n 口油井的位置,编程计算各油井到主管道之间的输油管道最小长度总和。
输入
文件第一行是油井数n,1<=n<=10000。接下来n行是油井的位置,每行2个整数x和y,-10000<=x,y<=10000。
输出
输出油井到主管道之间的输油管道最小长度总和。
样例输入
5
1 2
2 2
1 3
3 -2
3 3
样例输出
6
var a:array[0..10000] of longint;
x,i,t,n:longint;
procedure qk(low,high:longint);
var l,h,mid:longint;
begin
l:=low;h:=high;mid:=a[(l+h) div 2];
repeat
while (l<=high) and (a[l]
< mid) do inc(l);
while
(h>=low) and (a[h] > mid) do dec(h);
if l<=h then
begin
a[0]:=a[l];
a[l]:=a[h];
a[h]:=a[0];
inc(l);
dec(h);
end;
until l > h;
if l < high then qk(l,high);
if h > low then qk(low,h);
end;
begin
readln(n);
for i:=1 to n do readln(x,a[i]);
qk(1,n);
t:=0;x:=(1+n) div 2;
for i:=1 to n do t:=t+abs(a[i]-a[x]);
writeln(t);
end.
三)ss2299士兵站队
在一个划分成网格的操场上,n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表
示。士兵们可以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名
士兵。按照军官的命令,士兵们要整齐地列成一个水平队列,即排列成
(x,y),(x+1,y),…,(x+n-1,y)。如何选择x 和y的值才能使士兵们以最少的总移动步数排成一列。
编程任务:
计算使所有士兵排成一行需要的最少移动步数。
输入
输入士兵数n,1<=n<=10000。接下来n 行是
士兵的初始位置,每行2 个整数x 和y,-10000<=x,y<=10000。
输出
输出的第1 行中的数是士兵排成一行需要的最少移动步数。
样例输入
5
1 2
2 2
1 3
3 -2
3 3
样例输出
8
type sj=array[1..10001]of longint;
var x,y:array[1..10001]of longint;
i,mid,step,n,a,min:longint;
procedure px(l,r:longint; var y:sj);
var i,j,m,t:longint;
begin
i:=l; j:=r;
m:=y[(l+r)div 2];
repeat
while y[i] < m do inc(i);
while y[j] > m do dec(j);
if i <= j then
begin
t:=y[i]; y[i]:=y[j]; y[j]:=t;
inc(i); dec(j);
end;
until i >
j ;
if l < j
then px(l,j,y);
if r > i
then px(i,r,y);
end;
begin
readln(n);
for i:=1 to
n do
read(x[i],y[i]);
px(1,n,y);
mid:=y[n div
2+1];
step:=0;
for i:=1 to
n
do
step:=step+abs(y[i]-mid);
px(1,n,x);
for i:=1 to
n
do
x[i]:=x[i]-i+1;
px(1,n,x);
mid:=x[n div
2+1];
for i:=1 to
n
do
现在共有n个同学要排成一列,每个同学有两个属性:影响力和承受能力。给一个同学造成的心理创伤指数,等于所有在他前面同学的影响力之和,减去他的承受能力。
请安排一下排队顺序,尽量使受到心理创伤最大的同学少受创伤。
输入格式:
第1行是整数n,表示同学人数
第2~n+1行,每行两个自然数,分别是该同学的影响力和承受能力。
输出格式:
输出1行1个整数,为你安排的顺序中受到心理创伤最大的同学受到的创伤
输入样例:
3
10 3
2 5
3
输出样例:
2
问题分析:
排序,关键确定逆序条件。
用冒泡去理解,假如前面已经完全排序完毕,第i,j两个人的排序比较是:
sum+a[j]-b[i] vs sum+a[i]-b[j];
a[i]+b[i] vs
两值相等的话,谁的魅力a[i]小排前面
#include "bits/stdc++.h"
using namespace std;
int n;
struct demo{
bool cmp(demo x,demo y)
{
int main()
{
二)ss2303输油管道问题
某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n 口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。如果给定n口油井的位置,即它们的x 坐标(东西向)和y 坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置? 证明可规定时间内确定主管道的最优位置。
编程任务:
给定n 口油井的位置,编程计算各油井到主管道之间的输油管道最小长度总和。
输入
文件第一行是油井数n,1<=n<=10000。接下来n行是油井的位置,每行2个整数x和y,-10000<=x,y<=10000。
输出
输出油井到主管道之间的输油管道最小长度总和。
样例输入
5
1 2
2 2
1 3
3 -2
3 3
样例输出
6
var a:array[0..10000] of longint;
begin
end.
三)ss2299士兵站队
在一个划分成网格的操场上,n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表
示。士兵们可以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名
士兵。按照军官的命令,士兵们要整齐地列成一个水平队列,即排列成
(x,y),(x+1,y),…,(x+n-1,y)。如何选择x 和y的值才能使士兵们以最少的总移动步数排成一列。
编程任务:
计算使所有士兵排成一行需要的最少移动步数。
输入
输入士兵数n,1<=n<=10000。接下来n 行是
士兵的初始位置,每行2 个整数x 和y,-10000<=x,y<=10000。
输出
输出的第1 行中的数是士兵排成一行需要的最少移动步数。
样例输入
5
1 2
2 2
1 3
3 -2
3 3
样例输出
8
type sj=array[1..10001]of longint;
var x,y:array[1..10001]of longint;
procedure px(l,r:longint; var y:sj);
var i,j,m,t:longint;
begin
end;
begin