你能想到一个可以让我的程序给出错误答案的测试吗?

时间:2015-03-04 18:20:48

标签: c testing data-structures

我正在努力解决这个问题

http://acm.timus.ru/problem.aspx?space=1&num=2014

我已经让我的解决方案在提供的测试上工作了。当我提交我的解决方案时,我在第11次测试中得到了错误的答案。所以,请你考虑一下这样一个可以让我的程序给出错误答案的输入吗?

P.S。问题不是时间或内存不足。执行时间为0.015秒,使用的内存为214 KB。我猜这个测试很短,数字合理。

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

typedef struct letter
{
    int change;     // amount of money spent or gained
    int date;       // packed date, I will never need the actual date, I will just need which date is earlier (smaller), and which is later (greater)
    int sign : 1;       // minus one for plus, zero for minus
    int seen : 1;       // minus one for seen, zero otherwise
} Letter;

int packDate(int, int, int, int);       // we will not need to know the date, just their relation to each other
void printLetter(Letter *);         // for debugging, not implemented
void getTime(int *, int *, int *, int *);   // read time from input
void selectionSort(Letter *, int);      // sort the letters by date, to get them in chronological order
void letterCopy(Letter *, Letter *, int);   // copy one array of letters to another
long long check(Letter *, int);         // evaluate the debt
int binSearch(int, Letter *, int);      // find the index of letter with given date

int main()
{
    int n;
    scanf("%i", &n);
    getchar();
    Letter *pletters = (Letter *)malloc(sizeof(Letter) * n);
    int i;
    for (i = 0; i < n; ++i) {               // read letters
        char sign = getchar();
        pletters[i].sign = sign == '+' ? 1 : 0;
        scanf("%i", &pletters[i].change);
        getchar();
        int dd, MM, hh, mm;
        getTime(&dd, &MM, &hh, &mm);
        pletters[i].date = packDate(dd, MM, hh, mm);
        pletters[i].seen = 0;
    }                           // the letters are read
    Letter *plSorted = (Letter *)malloc(sizeof(Letter) * n);
    letterCopy(pletters, plSorted, n);          // make a copy of the letters array
    selectionSort(plSorted, n);             // sort copy, to get in historical order
    for (i = 0; i < n; ++i) {               // evaluate each letter in original order
        int si = binSearch(pletters[i].date, plSorted, n);  // find the position of this letter in historical order
        plSorted[si].seen = 1;                  // mark it in historical order as seen
        printf("%li\n", check(plSorted, n));            // evaluate debt, based on all seen letters, and print it
    }
    return 0;
}

int binSearch(int d, Letter *l, int n)
{
    int mid;
    int low = 0;
    int high = n - 1;
    while (low <= high) {
        mid = (low + high) / 2;
        if (d < l[mid].date) {
            high = mid - 1;
        } else if (d > l[mid].date){
            low = mid + 1;
        } else {
            return mid;
        }
    }
    return -1;
}

long long check(Letter *s, int n)
{
    int i;
    long long cash, debt;
    cash = debt = 0;
    for (i = 0; i < n; ++i) {
        if (s[i].seen) {
            if (s[i].sign) {
                cash += s[i].change;        // if letter states +, then add amount to Zhenya's cash
            } else {
                cash -= s[i].change;        // if he has money, he spends money from his cash
                debt += cash < 0 ? cash : 0;    // if he rans out of money, he will use credit card
                cash = cash < 0 ? 0 : cash; // if he used credit card, his cash is empty
            }
        }
    }
    return debt;
}

void letterCopy(Letter *s, Letter *d, int n)
{
    int i;
    for (i = 0; i < n; ++i) {
        d[i] = s[i];
    }
}

void selectionSort(Letter *l, int n)
{
    int i, j, min, mi;
    for (i = 0; i < n; ++i) {
        min = INT_MAX;
        mi = i;
        for (j = i; j < n; ++j) {
            if (l[j].date < min) {
                min = l[j].date;
                mi = j;
            }
        }
        Letter t = l[i];
        l[i] = l[mi];
        l[mi] = t;
    }
}

void getTwoDigits(int *);

void getTime(int *dd, int *MM, int *hh, int *mm)
{
    getTwoDigits(dd);
    getTwoDigits(MM);
    getTwoDigits(hh);
    getTwoDigits(mm);
}

void getTwoDigits(int *n)
{
    *n = 0;
    *n += (getchar() - '0') * 10;
    *n += getchar() - '0';
    getchar();
}

int packDate(int dd, int MM, int hh, int mm)
{
    mm += MM * 31 * 12 * 60 + dd * 12 * 60 + hh * 60;
    return mm;
}

代码在提供的测试中工作正常,在我在讨论部分找到的测试中。我想我可以尝试为特定的n生成所有测试,然后编写一个脚本来遍历所有测试,然后手动检查所有答案。在我开始之前,任何人都可以提出测试或者想法如何以最快速有效的方式进行测试吗?

2 个答案:

答案 0 :(得分:0)

是的我可以考虑很多测试,例如在程序类型aasdas的开头,按回车键,你去...你的程序会做疯狂的事情。

原因是你忽略scanf()的返回值,这是完全错误的,你必须检查它是否成功,否则你将从未初始化的变量中读取,这当然会导致很多问题。

因此每个scanf()都需要一个

if (scanf("%i", &n) != 1)
    doSomething_n_isUninitialized_Do_Not_useItsValue();

答案 1 :(得分:0)

问题在于一天24小时,而不是12小时