UVa 102 - 生态箱包装错误答案

时间:2015-07-07 05:57:49

标签: c

我正在研究UVa 102 - Ecological Bin Packing问题:

  

生态箱包装

     

背景

     

Bin装箱,或将某些重物的物体放置在受到某些限制的不同箱中,是历史上有趣的问题。一些装箱问题是NP完全的,但是适用于动态编程解决方案或近似最优的启发式解决方案。

     

在这个问题中,您将解决处理回收玻璃的装箱问题。

     

问题

     

回收玻璃需要将玻璃分为三类:棕色玻璃,绿色玻璃和透明玻璃。在这个问题中,您将获得三个回收箱,每个回收箱包含指定数量的棕色,绿色和透明瓶。为了回收利用,需要移动瓶子,使每个垃圾桶只包含一种颜色的瓶子。

     

问题是尽量减少移动的瓶子数量。您可以假设唯一的问题是最小化盒子之间的移动次数。

     

出于这个问题的目的,每个箱子具有无限的容量,唯一的限制是移动瓶子,使每个箱子包含单一颜色的瓶子。瓶子总数不会超过2 ^ 31。

     

输入

     

输入由一系列行组成,每行包含9个整数。一行中的前三个整数表示第1个箱子中的棕色,绿色和透明瓶子的数量,后三个表示第2个箱子中的棕色,绿色和透明瓶子的数量,以及最后一个三个整数表示3号箱中的棕色,绿色和透明瓶子的数量。

     

例如,行10 15 20 30 12 8 15 8 31表示箱1中有20个透明瓶,箱2中有12个绿色瓶子,箱3中有15个棕色瓶子。

     

一行上的整数将用一个或多个空格分隔。您的程序应该处理输入文件中的所有行。

     

输出

     

对于每行输入,将有一行输出指示什么颜色的瓶子进入哪个箱子以最小化瓶子移动的数量。您还应该打印最小数量的瓶子移动。

     

输出应包含三个大写字母“G”,“B”,“C”(代表颜色为绿色,棕色和透明)的字符串,表示与每个箱子相关联的颜色。

     

字符串的第一个字符表示与第一个bin相关联的颜色,字符串的第二个字符表示与第二个bin相关联的颜色,第三个字符表示与第三个bin相关联的颜色。

     

表示最小瓶子移动次数的整数应该在字符串后面。

     

如果棕色,绿色和透明箱的多个订单产生最小移动次数,则应打印代表最小配置的按字母顺序排列的第一个字符串。

     

示例输入

     

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

     

示例输出

     

BCG 30
  CBG 50

现在我被卡住了...... UVa在线评判系统给了我WA,但我无法弄明白为什么。

以下是我的代码:

#include <stdio.h>
#include <stdlib.h>

int getSumOfBottles(int bottles[3][3]){
    int i, j, sum;

    for(i = 0; i < 3; i++){
        for (j = 0; j < 3; j++){
            sum += bottles[i][j];
        }
    }

    return sum;
}


void showBGC(int inputNum){
    switch (inputNum){
        case 0:
            printf("B");
            break;
        case 1:
            printf("G");
            break;  
        case 2:
            printf("C");
            break;  
    }
}

/* method 2*/
/* just use 6 kinds of posibilities to count*/

int main(int argc, char *argv[]) {

    int i, j;

    /* char array, with ', B == 0, G == 1, C ==2 */
    char bcgText[3] = {'B', 'G', 'C'};

    /* since BCG should show up in the begining, move {0, 2, 1} */
    int posibleIndex[6][3] = {{0, 2, 1}, {0, 1, 2}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};

    int bottles[3][3];

    int sumBottles;
    int sumMove;

    int minMove;
    int minMoveIndex = 0;

    while(scanf("%d%d%d%d%d%d%d%d%d", &bottles[0][0], &bottles[0][1], &bottles[0][2], 
                                      &bottles[1][0], &bottles[1][1], &bottles[1][2],
                                      &bottles[2][0], &bottles[2][1], &bottles[2][2]) != EOF){

        sumBottles = getSumOfBottles(bottles);
        minMove = sumBottles;

        /* get the moves in each cases, and find the minMovements */
        for (i = 0; i < 6; i++){
            sumMove = sumBottles - (bottles[0][posibleIndex[i][0]] + bottles[1][posibleIndex[i][1]] + bottles[2][posibleIndex[i][2]]);

            if (sumMove < minMove){
                minMove = sumMove;
                minMoveIndex = i;
                /* printf("index %d, minMove %d", i, minMove); */
            }
        }

        /* one line output */
        printf("%c%c%c %d\n", bcgText[posibleIndex[minMoveIndex][0]], 
                              bcgText[posibleIndex[minMoveIndex][1]],
                              bcgText[posibleIndex[minMoveIndex][2]],  minMove);        
    }
    return 0;
}

有人可以给我一些提示吗?

1 个答案:

答案 0 :(得分:1)

你错过了一行“如果棕色,绿色和透明箱的多个订单产生最小移动次数,那么应该打印代表最小配置的按字母顺序排列的第一个字符串。”你的posibleIndex [6] [3]初始化应按{{0,2,1},{0,1,2},{2,0,1},{2,1,0},{1,0, 2},{1,2,0}}因为你已经将bcgText [3]数组初始化为{'B','G','C'}以维持词典排序。还有一件事,你应该将getSumOfBottles函数中声明的sum变量初始化为0.虽然即使没有初始化总和也会被接受,但这是一种不好的做法。