链接:https://vjudge.net/problem/UVA-509
记录这个题主要是来记录一下自己遇到的神奇的bug,避免再走弯路。
#include <iostream> #include <stdio.h> #include <cstring> //#define LOCAL using namespace std; char disk[7][105][66]; int d, s, b, check, exibs[105][66], flcnt; char d2h[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; //一种更简单的写法:="0123456789ABCDEF" struct Flaw { int df, bf, sf; } flaw[6800]; int get(int cd, int cb) { char c; bool f = true; for (int i = 1; i <= s; ++i) { c = getchar(); if (c == 'x') { if (exibs[cb][i] == 0) flcnt++, flaw[flcnt].df = cd, flaw[flcnt].bf = cb, flaw[flcnt].sf = i, exibs[cb][i] = 1; else f = false; } disk[cd][cb][i] = c; } disk[cd][cb][s + 1] = '\0'; //就是这句,要重新设置结束符,不然会跟以前记录的数据连在一起输出。。 return f; } void fix(int df, int bf, int sf) { int ans = 0; for (int i = 1; i <= d; ++i) { if (i != df) ans ^= disk[i][bf][sf] - '0'; } disk[df][bf][sf] = char((ans ^ check) + '0'); //注意位运算的优先级是很低的,要加括号保险(之前被这个坑了) } bool examine() { int t; for (int k = 1; k <= s; ++k) { for (int j = 1; j <= b; ++j) { t = 0; for (int i = 1; i <= d; ++i) { t ^= disk[i][j][k] - '0'; } if (t != check) return false; } } return true; } //输出16进制还可以用cout<< setiosflags(ios::uppercase)<< std::hex<< h 和 printf("%X", h); void print() { char output[50000] = "\0"; for (int i = 1; i <= b; ++i) { for (int j = 1; j <= d; ++j) { if ((i - 1) % d + 1 != j) { strcat(output, disk[j][i] + 1); //就在这里用了整租字符串,没有注意结束符号QAQ } } } int n = strlen(output); int t = n % 4; if (t) { n += 4 - t; for (int i = 1; i <= 4 - t; ++i) strcat(output, "0"); //注意一下strcat的用法 } for (int i = 0; i <= n - 4; i += 4) { t = 0; for (int j = i; j < i + 4; ++j) { t = t * 2 + (output[j] - '0'); } putchar(d2h[t]); } } int main() { #ifdef LOCAL freopen("in.in", "r", stdin); freopen("out.txt", "w", stdout); #endif int cnt = 0; char buf[3]; bool skf; while (scanf("%d%d%d", &d, &s, &b) && d) { fgets(buf, 2, stdin); //防止溢出,同样在强调,用getchar注意换行符,注意换行符,注意换行符 skf = false; memset(exibs, 0, sizeof(exibs)); flcnt = 0; printf("Disk set %d is ", ++cnt); check = (getchar() == 'E' ? 0 : 1); fgets(buf, 2, stdin); for (int i = 1; i <= d; ++i) { for (int j = 1; j <= b; ++j) { if (!get(i, j) && !skf) { printf("invalid."); skf = true; } } fgets(buf, 2, stdin); } if (!skf) { for (int i = 1; i <= flcnt; ++i) { fix(flaw[i].df, flaw[i].bf, flaw[i].sf); } if (examine()) { printf("valid, contents are: "); print(); } else printf("invalid."); } /*#ifdef LOCAL for (int i = 1; i <= d; ++i) { for (int j = 1; j <= b; ++j) printf("%s", disk[i][j] + 1); putchar('\n'); } #endif*/ putchar('\n'); } }
一开始弄错了d和b的次序,这种变量多的题目容易搞混。。
字符数组的bug折腾了我好久,最后还是靠构造数据找出来了,只能说幸好这种题的结果正确与否比较明显。
构造数据的话首先要考虑极端情况,一般就是从数值上或是可能的情况上入手。(要是能想到所有情况还构造什么数据啊啊啊)也要尽可能让程序的每个部分都得以测试。
其次要考虑多组数据,有可能前面的数据会对后面造成影响,例如这题。。如果难以观察可以把数据分开测试,在合并测试。