Codeforces-1089L & 1080A & 1065A & 1064A
- Codeforces-1089L-Lazyland
- Codeforces-1080A-Petya and Origami
- Codeforces-1065A-Vasya and Chocolate
- Codeforces-1064A-Make a triangle!
Codeforces-1089L-Lazyland
题目链接
题目大意
一个"懒岛",有n
个懒人(idlers
),国王给这n
个懒人分配k
个任务,告诉你懒人们选择的任务编号a[]
,现在的问题是,有些人选择了同样的任务,使得有些任务没有人做,于是国王要和这些选择了重复任务的某些人谈判,要他们选择别的任务,和每个人谈判有一个耗费的时间b[]
,现在要你求国王和哪些人谈判使得所有任务都有人做,且时间最少,求最少的时间。
解析
这个题目我是用优先队列(大根堆)来维护最小的没有人选择的岗位的几个时间:
- 使用
set
去重,判断没有重复的工作总共有多少个,如果k - set.size() == 0
则表示所有工作都有人选择了,则输出0
; - 否则,遍历
n
,先判断这个工作选择的人是否> 1
,如果不大于,就不要考虑了; - 否则就要选择这些人,但是只能选择
noChoseJob
,于是维护一个noChoseJob
大小的堆,并使用个map
来记录相同工作之间时间的最大值;
import java.io.BufferedInputStream;
import java.util.*;
/** question link : http://codeforces.com/problemset/problem/1089/L */
public class Main {
private final static int MAX = 100000;
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int n = cin.nextInt(), k = cin.nextInt(); // idlers num , jobs num
HashSet<Integer> set = new HashSet<>(); // judge
int[] a = new int[n], b = new int[n];
int[] times = new int[MAX];
for (int i = 0; i < n; i++) {
a[i] = cin.nextInt();
set.add(a[i]);
times[a[i]]++; // record the job be chosen number of times
}
for (int i = 0; i < n; i++)
b[i] = cin.nextInt();
int noChoseJob = k - set.size();
if (noChoseJob == 0) { // all idlers have job
System.out.println(0);
return;
}
Queue<Integer> pq = new PriorityQueue<>((o1, o2) -> o2 - o1); // the big heap
HashMap<Integer, Integer> maxMap = new HashMap<>();
for(int i = 0; i < n; i++){
if(times[a[i]] <= 1)
continue;
if(maxMap.get(a[i]) == null){
maxMap.put(a[i], b[i]);
}else{
Integer previous_max_ai = maxMap.get(a[i]);
if(previous_max_ai < b[i]){
if(noChoseJob == pq.size()){
if(previous_max_ai < pq.peek()) {
pq.poll();
pq.add(previous_max_ai);
}
}else { // if pq.size < noChoseJob, add directly
pq.add(previous_max_ai);
}
maxMap.put(a[i], b[i]); // update max
}else { // add b[i] to the pq directly
if(noChoseJob == pq.size()){
if(b[i] < pq.peek()) {
pq.poll();
pq.add(b[i]);
}
}else {
pq.add(b[i]);
}
}
}
}
long res = 0; // notice, must long
while(!pq.isEmpty())
res += pq.poll();
System.out.println(res);
}
}
Codeforces-1080A-Petya and Origami
题目链接
题目大意
邀请一个朋友需要三种卡片,且red = 2
、green = 5
、blue = 8
,现在要邀请n
个朋友,现在需要去买笔记本,每个笔记本notebook
里面只有一种颜色的卡片k
个,给出n
、k
,求买最少的笔记本个数;
解析
水题。。
#include <bits/stdc++.h>
typedef long long ll;
int main(int argc, char const **argv)
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, k;
std::cin >> n >> k;
ll res = 0;
ll red = 2 * n;
res += (red % k == 0) ? red/k : red/k + 1;
ll green = 5 * n;
res += (green % k == 0) ? green/k : green/k + 1;
ll blue = 8 * n;
res += (blue % k == 0) ? blue/k : blue/k + 1;
std::cout << res << std::endl;
return 0;
}
Codeforces-1065A-Vasya and Chocolate
题目链接
题目大意
买a
个巧克力棒可以得到额外的b
个巧克力棒,每个巧克力棒花费c
元,总共有s
元,问怎么买可以使得买的最多,最多是多少?
解析
水题。。
#include <bits/stdc++.h>
typedef long long ll;
int main(int argc, char const **argv)
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int T;
for(std::cin >> T; T--; ){
int s, a, b, c;
std::cin >> s >> a >> b >> c;
ll cb = s / c; // directly can get
ll sp = cb / a; // special get additional
ll res = 0; // result
res += cb;
res += sp * b; // remember to multiply b
std::cout<< res << std::endl;
}
return 0;
}
Codeforces-1064A-Make a triangle!
题目链接
题目大意
给你三角形的三条边a
、b
、c
,问如何延长某一条边使得三角形条件(任意两边之和大于第三边)成立,求延长的最小值。
解析
水题。。
#include <bits/stdc++.h>
int main(int argc, char const ** argv)
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int a,b,c;
std::cin >> a >> b >> c;
if(a+b > c && a+c > b && b+c > a)
std::cout << 0 << std::endl;
else {
int _min = std::min(std::min(a, b), c);
int _max = std::max(std::max(a, b), c);
int _mid = a + b + c - _min - _max;
for(int i = 1; ; i++){
if( _min+i+_mid > _max && _min+i+_max > _mid && _mid+_max > _min+i){
std::cout << i << std::endl;
break;
}
}
}
return 0;
}
更好的方式:
#include <bits/stdc++.h>
int main(int argc, char const **argv)
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int a, b, c;
std::cin >> a >> b >> c;
int minn = std::max(a-b-c, std::max(b-a-c,c-a-b));
std::cout << std::max(minn + 1, 0) << std::endl;
return 0;
}