在urionlinejudge

时间:2016-01-10 16:21:16

标签: algorithm data-structures

你的老板告诉你,你只有一台电脑来完成一些任务。他们每个人都为公司赚了一笔钱,并且必须从现在开始计算。之后,它不再被执行,没有更多的价值。计算机每小时完成一项任务。

你想给老板留下深刻印象,这样他就可以给你一个晋升机会。为此,您打算使用您的编程技巧来选择执行哪些任务,以最大限度地减少损失的金额。

输入

输入由多个测试用例组成,以文件结尾结束。每一个都描述了一个任务列表,并以两个整数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);
        }
    }   
}

1 个答案:

答案 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

这些可能只是你应该解决的主要问题。但是你可以看到这个算法需要重新思考。

建议修复(剧透)

  • 处理按照您的方式排序的所有任务,但对于可能的最高点,设置等于true,低于结束时间。
  • 如果未找到下限,则无法完成任务,并且应将其值添加到损失中

完整代码:

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。以及您和其他人可能从中受益的其他最佳实践。