首页 > 试题广场 >

小美的跑腿代购

[编程题]小美的跑腿代购
  • 热度指数:2009 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

       小美的一个兼职是美团的一名跑腿代购员,她有n个订单可以接,订单编号是1~n,但是因为订单的时效性,他只能选择其中m个订单接取,精明的小美当然希望自己总的获利是最大的,已知,一份订单会提供以下信息,跑腿价格v,商品重量w kg,商品每重1kg,代购费用要加2元,而一份订单可以赚到的钱是跑腿价格和重量加价之和。小美可是开兰博基尼送货的人,所以自然不会在意自己会累这种事情。请问小美应该选择哪些订单,使得自己获得的钱最多。

      请你按照选择的订单编号的从小到大顺序,如果存在多种方案,输出订单编号字典序较小的方案。


输入描述:

输入第一行包含两个正整数n,m,表示订单的数量和小美可以接的订单数量(1<=n,m<=10000)

接下来有n行,第i行表示i-1号订单的信息。每行有两个正整数v和w,表示一个订单的跑腿价格和商品重量。(1<=v,w<=1000)



输出描述:

输出包含m个1~n之间的正整数,中间用空格隔开,表示选择的订单编号。

示例1

输入

5 2
5 10
8 9
1 4
7 9
6 10

输出

2 5
二次排序走一波
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int[][] arr=new int[n][2];
        for (int i = 0; i < n; i++) {
            int v=sc.nextInt();
            int w=sc.nextInt();
            arr[i]=new int[]{i+1,v+2*w};
        }
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o2[1]-o1[1];
            }
        });
        PriorityQueue<Integer> queue=new PriorityQueue<>();
        for (int i = 0; i < m; i++) {
            queue.offer(arr[i][0]);
        }
        for (int i = 0; i < m; i++) {
            System.out.print(queue.poll()+" ");
        }

    }
}


发表于 2021-06-05 20:59:29 回复(0)
堆排序,python中只有最小堆heapq,所以push要取负
import heapq
# 总订单n,取m个
n,m=list(map(int,input().split()))
# 存放订单价格,索引是其订单编号
heap=[]
for i in range(1,n+1):
    v,w=list(map(int,input().split()))
    heapq.heappush(heap,[-(v+2*w),i])

ans=[]
for j in range(m):
    ans.append(heapq.heappop(heap)[-1])
    #w,i=heapq.heappop(heap)
    #ans.append(i)

#ans.sort()
#for x in ans:
#    print(x,end=" ")
print(" ".join(str(i) for i in sorted(ans)))



发表于 2021-08-14 22:41:47 回复(0)
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;

typedef struct Node {
	int id;
	int income;
	Node() {}
	Node(int id, int v, int w) {
		this->id = id;
		income = v + (w * 2);
	}
}node;

bool cmp(node x,node y) {
	if (x.income == y.income) return x.id < y.id;  //收入相等,编号从小到大
	return x.income > y.income;	//收入不相等,收入从大到小 
}

int main() {
	int n, m;
	cin >> n >> m;

	vector<node> goods(n);

	int v = 0, w = 0;
	for (int i = 0; i < n; i++) {
		cin >> v >> w;
		goods[i] = Node(i + 1, v, w);
	}

	sort(goods.begin(), goods.end(), cmp);
	priority_queue<int, vector<int>, greater<int>> pq;
	for (int i = 0; i < m; i++) {
		pq.push(goods[i].id);
	}

	for (int i = 0; ; i++) {
		if (i == m) break;
		cout << pq.top() << " ";
		pq.pop();
	}

	return 0;
}

发表于 2021-03-09 19:47:01 回复(0)
很简单的一个二次排序。首先按照订单的收入降序排列,对于收入相等的情况,由于要保证我们输出的订单序列字典序最小,这时候优先选择订单号小的,即按收入降序,按编号升序。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] strNM = br.readLine().trim().split(" ");
        int n = Integer.parseInt(strNM[0]);
        int m = Integer.parseInt(strNM[1]);
        Node[] goods = new Node[n];
        for(int i = 0; i < n; i++){
            String[] params = br.readLine().trim().split(" ");
            int v = Integer.parseInt(params[0]);
            int w = Integer.parseInt(params[1]);
            goods[i] = new Node(i + 1, v, w);
        }
        Arrays.sort(goods, new Comparator<Node>() {
            @Override
            public int compare(Node node1, Node node2) {
                if(node1.income > node2.income){
                    return -1;
                }else if(node1.income < node2.income){
                    return 1;
                }else{
                    return node1.id - node2.id;
                }
            }
        });
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for(int i = 0; i < m; i++)
            pq.offer(goods[i].id);
        for(int i = 0; i < m; i++)
            System.out.print(pq.poll() + " ");
    }
}

class Node {
    public int income;
    public int id;
    public Node(int id, int v, int w) {
        income = v + 2*w;
        this.id = id;
    }
}


发表于 2021-03-01 19:45:54 回复(0)
不是说好了n<=10000吗,这坑爹数据为什么会有n=50000。。。。。。。
发表于 2021-03-24 20:41:46 回复(0)
这题各种条件有点多,要注意审题!
处理输入的时候,把w乘2加到v上,然后把位置存到w处;
排序,当获得的钱相等时,按照标号升序排列,否则按照获得钱数的降序排列;
取前m个作为答案输出;
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int[] int1 = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        int n = int1[0];
        int m = int1[1];
        Integer[][] map = new Integer[n][2];
        for (int i = 0; i < n; i++) {
            int[] int2 = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
            int v = int2[0];
            int w = int2[1];

            v += 2 * w;
            map[i][0] = v;
            map[i][1] = i + 1;
        }
        Arrays.sort(map, (o1, o2) -> {
            if (o1[0] == o2[0]) {
                return o1[1] - o2[1];
            } else {
                return o2[0] - o1[0];
            }
        });
        int[] res = new int[m];
        for (int i = 0; i < m; i++) {
            res[i] = map[i][1];
        }
        Arrays.sort(res);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < m; i++) {
            sb.append(res[i]).append(" ");
        }
        sb.deleteCharAt(sb.length() - 1);
        System.out.println(sb);
    }
}


发表于 2022-09-06 20:30:35 回复(0)
明明说了如果【存在多种方案,输出订单编号字典序较小的方案】,按字典序反而错,题解不管字典序都对了
发表于 2022-08-19 16:30:50 回复(0)
const [n, m] = readline().split(' ').map(Number)
let value = new Array(n).fill(0)
for(let i = 0; i < n; i++) {
    const [v, w] = readline().split(' ').map(Number)
    value[i] = {value: v + w * 2, index: i}
}
value = value.sort((a, b) => { // 对不同订单的收入进行从大到小的排序
    if(b.value !== a.value) {
        return b.value - a.value // 收入不同, 收入从大到小
    }else {
        return a.index - b.index // 收入相同, 编号从小到大
    }
})
const ans = new Array(m)
for(let i = 0; i < m; i++) {
    ans[i] = value[i].index + 1
}
console.log(ans.sort((a, b) => a - b).join(' '))

发表于 2022-05-26 00:33:43 回复(0)
#include<bits/stdc++.h>

using namespace std;

const int N = 50005;
const int M = 50005;

int v[N];
int w[N];
int flag[M];
int ans[M];
//int allsum[N];

bool cmp(pair<int,int>& a,pair<int,int> &b){
    if(a.first == b.first) return a.second > b.second;
    return a.first < b.first;
}

vector<pair<int,int>>good;

int main(){
    int n,m;
    cin >> n >> m;
    for(int i = 0;i < n;i++){
        cin >> v[i]>>w[i];
    }
    int cnt = 0;
    vector<pair<int,int>>good;
    priority_queue<int,vector<int>,greater<int>>que;
    for(int i = 0;i < n;i++){
       int  allsum = v[i] + 2 * w[i];
        good.push_back(make_pair(allsum,i));
    }

     sort(good.begin(),good.end(),cmp);
     for(int i = n - 1; i > n - 1 - m;i--){
         ans[n - 1 - i] = good[i].second  + 1;
    }
     sort(ans,ans + m);
    for(int i = 0 ;i < m;i++){
      i!= 0&& cout << " ";
        cout << ans[i] ;
     }
    return 0;
}

发表于 2022-03-30 21:22:16 回复(0)
n, m = list(map(int, input().split()))

import heapq
heap = []
hashmap = {}
for i in range(m):
    pair = list(map(int, input().split()))
    heapq.heappush(heap, pair[0]+pair[1]*2)
    if pair[0]+pair[1]*2 not in hashmap:
        hashmap[pair[0]+pair[1]*2] = [i+1]
    else:
        hashmap[pair[0]+pair[1]*2] += [i+1]
for i in range(m, n):
    pair = list(map(int, input().split()))
    if pair[0]+pair[1]*2 > heap[0]:
        if len(hashmap[heap[0]]) == 1:
            hashmap.pop(heap[0])
        else:
            hashmap[heap[0]].pop()
        if pair[0]+pair[1]*2 not in hashmap:
            hashmap[pair[0]+pair[1]*2] = [i+1]
        else:
            hashmap[pair[0]+pair[1]*2] += [i+1]
        heapq.heapreplace(heap, pair[0]+pair[1]*2)
re = []
for j in hashmap.values():
    re += j
re.sort()
print(" ".join(map(str, re)))
偷懒一波~
发表于 2021-10-01 12:07:47 回复(0)
JavaScript的sort()默认是字典排序而不是根据数值排序,一定要手动加回调函数,大坑
发表于 2021-09-09 19:29:52 回复(0)

TOP K 最小堆

import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        //输入
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), m = in.nextInt();
        int[] v = new int[n], w = new int[n];
        for (int i = 0; i < n; i++) {
            v[i] = in.nextInt();
            w[i] = in.nextInt();
        }

        //最小堆(价值升序 序号降序)
        PriorityQueue<int[]> minHeap = new PriorityQueue<>((o1, o2) -> o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0]);
        //PriorityQueue<int[]> minHeap = new PriorityQueue<>((o1, o2) -> o1[0] - o2[0]);
        for (int i = 0; i < n; i++) {
            //价值
            int val = v[i] + 2 * w[i];
            if (minHeap.size() < m) {
                minHeap.offer(new int[]{val, i + 1});
            } else {
                //最小堆 堆顶元素
                int[] T = minHeap.peek();
                if (T[0] < val) {
                    minHeap.poll();
                    minHeap.offer(new int[]{val, i + 1});
                }
                //此处省略了判断T[0]==val&&i<T[1]情况,因为i逐步增大,那么最小堆中的T[k]值必然小于i值
            }
        }

        //输出
        int[] res = new int[m];
        int idx = 0;
        while (!minHeap.isEmpty()) {
            res[idx++] = minHeap.poll()[1];
        }
        //快排
        Arrays.sort(res);
        for (int i = 0; i < m; i++) {
            System.out.printf(String.valueOf(res[i]));
            if (i != m) {
                System.out.printf(" ");
            }
        }
    }
}
发表于 2021-08-24 22:48:47 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int orderNum=sc.nextInt();
        int orderNumAccept=sc.nextInt();
        PriorityQueue<Order> minPQ=new PriorityQueue<>(orderNumAccept+1,(order1,order2)->{
            if(order1.money!=order2.money)
                return order1.money-order2.money;
            else
                return order2.id-order1.id;
        });
        for(int i=1;i<=orderNum;++i){
            int part1=sc.nextInt();
            int part2=sc.nextInt()*2;
            Order order=new Order(i,part1+part2);
            minPQ.add(order);
            if(minPQ.size()>orderNumAccept)
                minPQ.remove();
        }
        ArrayList<Integer> orderIds=new ArrayList<>();
        for(Order order:minPQ)
            orderIds.add(order.id);
        Collections.sort(orderIds);
        for(Integer id:orderIds)
            System.out.print(id+" ");
    }
}
class Order{
    int id;
    int money;
    public Order(int id,int money){
        this.id=id;
        this.money=money;
    }
}

发表于 2021-08-07 21:18:31 回复(0)