Senior's Gun
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
Xuejiejie is a beautiful and charming sharpshooter.
She often carries
n guns, and every gun has an attack power
a[i] .
One day, Xuejiejie goes outside and comes across
m monsters, and every monster has a defensive power
b[j] .
Xuejiejie can use the gun
i to kill the monster
j , which satisfies
b[j]≤a[i] , and then she will get
a[i]−b[j] bonus .
Remember that every gun can be used to kill at most one monster, and obviously every monster can be killed at most once.
Xuejiejie wants to gain most of the bonus. It's no need for her to kill all monsters.
Input
In the first line there is an integer
T , indicates the number of test cases.
In each case:
The first line contains two integers
n ,
m .
The second line contains
n integers, which means every gun's attack power.
The third line contains
m integers, which mean every monster's defensive power.
1≤n,m≤100000 ,
−109≤a[i],b[j]≤109 。
Output
For each test case, output one integer which means the maximum of the bonus Xuejiejie could gain.
Sample Input
Sample Output
Source
BestCoder Round #47 ($)
/************************************************************************/
附上该题对应的中文题
Senior's Gun
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
学姐姐是一个酷酷的枪手。
她常常会随身携带nn把枪,每把枪有一个攻击力a[i]a[i]。
有一天她遇到了mm只怪兽,每只怪兽有一个防御力b[j]b[j]。现在她决定用手中的枪消灭这些怪兽。
学姐姐可以用第ii把枪消灭第jj只怪兽当且仅当b[j]\leq a[i]b[j]≤a[i],同时她会获得a[i]-b[j]a[i]−b[j]的分数。
每把枪至多只能使用一次,怪兽死后也不会复活。现在学姐姐想知道她最多能得到多少分(她可以不用消灭所有的怪兽)。
输入描述
第一行包含一个整数TT,表示测试数据组数。
对于每组测试数据:
第一行包含两个整数n,mn,m,表示枪的数量和怪兽的数量。
第二行包含nn个整数a[i]a[i],表示枪的攻击力。
第三行包含mm个整数b[j]b[j],表示怪兽的防御力。
1\leq n, m\leq 1000001≤n,m≤100000, -10^9 \leq a[i], b[j]\leq 10^9−109≤a[i],b[j]≤109。
输出描述
对于每组测试数据,输出一个整数表示对应的答案。
输入样例
1
2 2
2 3
2 2
输出样例
1
/****************************************************/
出题人的解题思路:
容易发现最后的方案一定是攻击力最强的k把枪消灭了防御力最弱的k只怪物,那么我们对枪和怪物排序后二分出最多能够使用的枪有多少把,然后再枚举使用几把枪更新答案即可。复杂度
O(nlogn)O(nlogn)
。
该题简单理解起来就是一把手枪杀一只怪兽,当且仅当手枪的攻击力a[i]大于等于怪兽的防御力b[j]时可以击杀,此时能获得相应的分数a[i]-b[j],题目要求求出最终获得的最高得分。
或许一开始,你会纠结于到底怎么取策略最优,是取尽可能多的手枪比较好呢,还是优先选取最大攻击的手枪与最小防御的怪兽来得好一些,然后是不是会有后续取不了等等影响,接着就各种混乱。。。
好了,各种想法都先收回来,不管一开始有没有头绪,还是说想法对与错的问题,我们都可以先这么考虑,为了使分数尽可能高,取的分数再低都要比没取来得高一些,而能取的自然是a[i]>b[j]的情况(a[i]=b[j]的情况取不取均可,反正不影响分数)。然后再从取的里面来想想,不管你按什么顺序取进来的,只要是取进来的满足a[i]>b[j],那我的得分是固定的,因为
所取枪攻击力的总和-怪兽防御力的总和就是你的得分,这个是固定的
。所以只要你取尽可能多的枪和怪兽进来,就可以使得你的分数越来越高。那如何取尽可能多的进来呢,那就
按攻击力递减、防御力递增的顺序取
,满足a[i]>b[j]都加进得分。
举个例子
枪的攻击力 4 2 5 7
怪兽防御力 3 4 1 8
首先排个序 (攻击力递增 防御力递减)
枪的攻击力 7 5 4 2
怪兽防御力 1 3 4 8
红色为能取部分,分数为8
排序算法只要时间复杂度是O(nlogn)以下的都是可以过此题的,一般都直接sort的吧
我讲得可能不怎么好,若有什么疑问,欢迎留下评论,谢谢
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int inf = 1000000000;
int a[N],b[N];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int t,n,m,i,j;
__int64 ans;
scanf("%d",&t);
while(t--)
{
ans=0;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<m;i++)
scanf("%d",&b[i]);
sort(a,a+n,cmp);
sort(b,b+m);
for(i=0,j=0;i<n&&j<m&&a[i]>b[j];i++,j++)
ans+=(a[i]-b[j]);
printf("%I64d\n",ans);
}
return 0;
}
菜鸟成长记