【杭电2015年12月校赛C】【双指针 or 二分 语文题】The collector’s puzzle 每个物品装在最适合的箱子中

8 篇文章 0 订阅
3 篇文章 0 订阅

The collector’s puzzle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1034    Accepted Submission(s): 233


Problem Description
There is a collector who own many valuable jewels. He has a problem about how to store them. There are M special boxes. Each box has a value. And each of the N jewels has a value too.  
The collector wants to store every jewel in one of the boxs while minimizing the sum of difference value.  
The difference value between a jewel and a box is: |a[i] - b[j]|, a[i] indicates the value of i-th jewel, b[j] indicates the value of j-th box.
Note that a box can store more than one jewel.

Now the collector turns to you for helping him to compute the minimal sum of differences.
 

Input
There are multiple test cases.
For each case, the first line has two integers N, M (1<=N, M<=100000).
The second line has N integers, indicating the N jewels’ values.
The third line have M integers, indicating the M boxes’ values.
Each value is no more than 10000.
 

Output
Print one integer, indicating the minimal sum of differences.
 

Sample Input
  
  
4 4 1 2 3 4 4 3 2 1 4 4 1 2 3 4 1 1 1 1
 

Sample Output
  
  
0 6
 


#include<stdio.h>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<ctype.h>
#include<string.h>
#include<vector>
#include<set>
#include<map>
using namespace std;
int casenum,casei;
typedef long long LL;
const int N=20005;
int n,m;
int a[100010];
int b[100010];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;++i)scanf("%d",&a[i]);    
        for(int i=1;i<=m;++i)scanf("%d",&b[i]);
        sort(b+1,b+m+1);
        int ans=0;
        for(int i=1;i<=n;++i)
        {
            int p=lower_bound(b+1,b+m+1,a[i])-b;
            int tmp=1e9;
            if(p<=m)tmp=min(tmp,abs(a[i]-b[p]));
            if(p>1)tmp=min(tmp,abs(a[i]-b[p-1]));
            ans+=tmp;
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*
【trick&&吐槽】
这题题意是很坑的。
The difference value between a jewel and a box is: |a[i] - b[j]|, a[i] indicates the value of i-th jewel, b[j] indicates the value of j-th box.
这里应该说,对于物品i,如果它被放在箱子j中,那么……

同时我的理解能力也捉急了。自己自行脑补成了——
成本是∑|箱子i的价值 - 箱子i中物品的价值|

然后感觉这题是神题不可做,以至于拖延了很久,后来还出了新问题。
不然这场校赛不至于打这么差的TwT。下次加油!

ps:对于trick,这题二分的时候要处理好边界问题。

【题意】
有n个物品,我们要把它们一个不漏地放进m个箱子中。1<=n,m<=1e5。

每个物品和每个箱子都有一定的价值。每个箱子体积无限,可以任意放物品。
如果物品i放在箱子j中,那么对成本的贡献就是|a[i]-b[j]|
让你设定装箱方案,输出最小的答案。

【类型】
双指针 or 二分 语文题

【分析】
显然,对于每个物品,选择和它价值最接近的箱子即可。
于是,我们的做法就可以是——

1,先把箱子和物品都升序排序,然后双指针搞搞
2,把箱子按照升序排序,然后对于每个物品,二分查找与其价值最接近的箱子

【时间复杂度&&优化】
两者的时间复杂度分别是——
1,O(nlogn + mlogm)
2,O(mlogm + nlogm)

*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值