题目链接如下:
起先写的代码比较复杂,后来参考这位大神【UVA 509 --- RAID!】模拟+位运算_uva509-CSDN博客 的代码修改了思路,代码如下:
(这里关键点就是,parity block和data block其实可以一致处理,不需要区分。)
#include <cstdio>
#include <algorithm>
#include <string>
// #define debug
int d, s, b, kase = 0;
char op[5];
char data[6][100][64];
char line[6410];
bool flag;
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
while(scanf("%d", &d) == 1 && d){
scanf("%d %d %s", &s, &b, op);
flag = true;
for(int i = 0; i < d; ++i){
scanf("%s", line);
for(int j = 0; j < b; ++j){
for(int k = 0; k < s; ++k){
data[i][j][k] = line[j * s + k];
}
}
}
for(int j = 0; j < b; ++j){
for(int k = 0; k < s; ++k){
int ix = -1;
int x = 0;
for(int i = 0; i < d; ++i){
if(data[i][j][k] == 'x'){
if(ix != -1){
k = s;
j = b;
flag = false;
break;
}
ix = i;
} else{
x ^= data[i][j][k] - '0';
}
}
if(ix == -1){
if((op[0] == 'E' ? 0 : 1) != x){
flag = false;
k = s;
j = b;
break;
}
} else{
data[ix][j][k] = (op[0] == 'E' ^ x) ? '0' : '1';
}
}
}
if(!flag){
printf("Disk set %d is invalid.\n", ++kase);
continue;
}
std::string str;
for(int j = 0; j < b; ++j){
for(int i = 0; i < d; ++i){
for(int k = 0; k < s; ++k){
if(i != j % d){
str.push_back(data[i][j][k]);
}
}
}
}
while(str.size() % 4){
str.push_back('0');
}
printf("Disk set %d is valid, contents are: ", ++kase);
for(int i = 0; i < str.size() / 4; ++i){
int tmp = ((str[4 * i] - '0') << 3) + ((str[4 * i + 1] - '0') << 2) + ((str[4 * i + 2] - '0') << 1) + str[4 * i + 3] - '0';
printf("%X", tmp);
}
printf("\n");
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
原先的代码如下(也能AC,但思路比较繁琐):
#include <cstdio>
#include <algorithm>
#include <string>
// #define debug
int d, s, b, cnt, pivot, kase = 0;
char op[5];
char data[6][100][64];
char line[6410];
int missing[6410];
bool flag;
char table[] = "0123456789ABCDEF";
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
while(scanf("%d", &d) == 1 && d){
scanf("%d %d %s", &s, &b, op);
std::fill(missing, missing + s * b, 0);
flag = true;
for(int i = 0; i < d; ++i){
scanf("%s", line);
for(int j = 0; j < b; ++j){
for(int k = 0; k < s; ++k){
data[i][j][k] = line[j * s + k];
if(line[j * s + k] == 'x'){
missing[j * s + k]++;
if(flag && missing[j * s + k] > 1){
flag = false;
}
}
}
}
}
if(!flag){
printf("Disk set %d is invalid.\n", ++kase);
continue;
}
for(int j = 0; j < b; ++j){
for(int k = 0; k < s; ++k){
cnt = 0;
for(int i = 0; i < d; ++i){
if(i == j % d){
continue;
}
if(data[i][j][k] == '1'){
cnt++;
} else if(data[i][j][k] == 'x'){
pivot = i;
}
}
cnt %= 2;
if(missing[j * s + k] == 0 || data[j % d][j][k] == 'x'){
if((op[0] == 'E' && cnt) || (op[0] == 'O' && !cnt)){
if(data[j % d][j][k] == 'x'){
data[j % d][j][k] = '1';
} else if(data[j % d][j][k] == '0'){
flag = false;
j = b;
break;
}
} else{
if(data[j % d][j][k] == 'x'){
data[j % d][j][k] = '0';
} else if(data[j % d][j][k] == '1'){
flag = false;
j = b;
break;
}
}
} else{
if((op[0] == 'E' && !cnt && data[j % d][j][k] == '0') || (op[0] == 'E' && cnt && data[j % d][j][k] == '1')
|| (op[0] == 'O' && !cnt && data[j % d][j][k] == '1') || (op[0] == 'O' && cnt && data[j % d][j][k] == '0')){
data[pivot][j][k] = '0';
} else{
data[pivot][j][k] = '1';
}
}
}
}
if(!flag){
printf("Disk set %d is invalid.\n", ++kase);
continue;
}
printf("Disk set %d is valid, contents are: ", ++kase);
std::string str;
for(int j = 0; j < b; ++j){
for(int i = 0; i < d; ++i){
for(int k = 0; k < s; ++k){
if(i != j % d){
str.push_back(data[i][j][k]);
}
}
}
}
while(str.size() % 4){
str.push_back('0');
}
for(int i = 0; i < str.size() / 4; ++i){
int tmp = 8 * (str[4 * i] - '0') + 4 * (str[4 * i + 1] - '0') + 2 * (str[4 * i + 2] - '0') + str[4 * i + 3] - '0';
printf("%c", table[tmp]);
}
printf("\n");
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
文章讲述了作者在解决UVA509问题时,通过参考大神的代码并修改思路,将parityblock和datablock的处理统一,简化了位运算,以提高代码效率。
713

被折叠的 条评论
为什么被折叠?



