你的老板告诉你,你只有一台电脑来完成一些任务。他们每个人都为公司赚了一笔钱,并且必须从现在开始计算。之后,它不再被执行,没有更多的价值。计算机每小时完成一项任务。
你想给老板留下深刻印象,这样他就可以给你一个晋升机会。为此,您打算使用您的编程技巧来选择执行哪些任务,以最大限度地减少损失的金额。
输入
输入由多个测试用例组成,以文件结尾结束。每一个都描述了一个任务列表,并以两个整数N(1≤N)和H(H≤1000)开始,它们分别是任务数和计算机可用的小时数。然后跟随N行,每行有两个整数v(1≤v≤1000)和t(1≤t≤H)。
输出
对于每个测试用例,输出一个带有表示最小损失金额的整数的行。
Sample Input Sample Output
3 3 0
5 1 3
10 2
20 3
4 2
1 2
2 1
4 1
2 2
我正在解决许多复杂的测试用例,如下所示,获得预期的结果但仍然在提交时得到100%错误答案。我的方法是根据货币价值按降序排序数组,然后低于逻辑。我的算法出了什么问题?
Input Output
5 3 30
10 1 30
20 2 1
50 2 0
40 3
30 3
4 5 test case 1
10 1
20 1
50 2
40 2
6 5 test case 2
10 1
12 4
15 5
20 5
1 5
30 5
3 1000
1000 1000
2 1
3 3
在下面的代码中 - 测试用例1(4 5)和测试用例2(6 5)工作正常,因为测试用例1的测量较少,测试用例2中的大多数任务可以在5小时内完成,所以等号尚未设定为真。
while(hours < H && z < N)
{
if(equal[Arr[z].getT()]!=true && hours<tlarge) {
loss -= Arr[z].getV();
equal[Arr[z].getT()]=true;
hours++;
}
else
{
int time=Arr[z].getT()-1;
while(time>0)
{
if(equal[time]==false)
{
loss -= Arr[z].getV();
hours++;
if(Arr[z].getT()<=hours)
{
int time1 = Arr[z].getT()-1;
while(time1>0)
{
equal[time1]=true;
time1--;
}
}
break;
}
time--;
}
}
z++;
}
这是我的代码 -
class Entry
{
private int v;
private int t;
Entry(int v, int t) {
this.v = v;
this.t = t;
}
public int getV() {
return v;
}
public int getT() {
return t;
}
}
public class Main {
public final static Entry[] Arr = new Entry[1003];
public static void main (String[] args) throws java.lang.Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true){
String T = in.readLine();
if(T==null) {
break;
}
String[] spl = T.split(" ");
int N = Integer.parseInt(spl[0]);
int H = Integer.parseInt(spl[1]);
int Num = N;int tlarge = 0;
int hours = 0;int loss = 0;int z=0,y=0;
boolean equal[] = new boolean[1003];
while( Num > 0)
{
String oper = in.readLine();
String[] op = oper.split(" ");
int v = Integer.parseInt(op[0]);
int t = Integer.parseInt(op[1]);
Arr[Num-1] = new Entry(v,t);
Num--;
}
while(y<N)
{
loss += Arr[y].getV();
if(Arr[y].getT()>tlarge) tlarge=Arr[y].getT();
equal[Arr[y].getT()]=false;
y++;
}
QuickSort( 0, N-1);//from zero to no of tasks
while(hours < H && z < N)
{
if((equal[Arr[z].getT()]!=true) || hours<Arr[z].getT()) {
if(Arr[z].getT()<=tlarge) {
if(z<tlarge) {
loss -= Arr[z].getV();
equal[Arr[z].getT()]=true;
hours++;
}
}
}
z++;
}
System.out.printf("%d\n",loss);
}
}
}
答案 0 :(得分:0)
1)将数组equal
设置为false
范围[0,N-1]
。但它实际上用于[0,H]
范围,并且H
不应该小于N
。这意味着可能存在一个影响交叉测试用例。
2)
if(z<tlarge)
为什么只在排序数组中的索引小于tlarge
时才执行该任务?
4 2
10 1
10 1
10 1
1 2
expected: 20
result: 21
3)您没有为您使用的时间段设置等于true。
if((equal[Arr[z].getT()]!=true) || hours<Arr[z].getT()) {
if(Arr[z].getT()<=tlarge) {
if(z<tlarge) {
loss -= Arr[z].getV();
equal[Arr[z].getT()]=true;
hours++;
}
}
}
即使已经拍摄了这个插槽,你也可以通过它。
4 4
1 1
5 2
5 2
1 4
expected: 1
result: 0
这些可能只是你应该解决的主要问题。但是你可以看到这个算法需要重新思考。
完整代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static class Entry implements Comparable<Entry> {
private final int v, t;
Entry(int v, int t) {
this.v = v;
this.t = t;
}
public int getV() {
return v;
}
public int getT() {
return t;
}
@Override
public int compareTo(Entry oth) {
if(this.v == oth.v){
Integer.signum(this.t - oth.t);
}
return Integer.signum(oth.v - this.v);
}
}
public static void main(String[] args) throws java.lang.Exception {
final Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int N = in.nextInt();
int H = in.nextInt();
Entry[] arr = new Entry[N];
for(int i=0;i<N;i++) {
int v = in.nextInt();
int t = in.nextInt();
arr[i] = new Entry(v, t);
}
Arrays.sort(arr);
Entry[] entryByHour = new Entry[H+1];
int loss = 0;
for(int i=0;i<arr.length;i++){
int j=arr[i].t-1;
while(j>=0 && entryByHour[j] != null){
j--;
}
if(j < 0){
loss += arr[i].v;
}else{
entryByHour[j] = arr[i];
}
}
System.out.printf("%d\n", loss);
}
in.close();
}
}
您也可以在codereview上将代码置于<{3}}。我觉得你习惯用c或c ++编程。但是在java中,你可以更轻松,更清晰地完成很多事情。与使用Entry
上的Arrays界面排序一样使用IComparable。以及您和其他人可能从中受益的其他最佳实践。