这道题真的是日了狗了,被一个如何跳过给定的block卡了半天,也是非常的无奈啊。还是自己的思维有局限性啊。
思路是这样的:
将数据保存到数组中,就像题目中给定的那样,然后再进行计算,遇到冗余的block的时候就跳过。
要注意的是,起始在输入的时候,就可以判断出是否是valid,但是我没有这么做,因为这样时间并不会减少很多,但是编程的复杂度却高了不少。
下面贴上代码
#include<cstdio> #include<cstring> #include<string> using namespace std; char RAID[100][6500];//0~63 64~127 int num_disk,num_bit,num_block; int flag_en_odd;//0是偶校验,1是奇校验 bool initial() { if(scanf("%d%d%d",&num_disk,&num_bit,&num_block)==3&&num_disk) { char s[5]; scanf("%s",s); if(s[0]=='O') { flag_en_odd=1; } else { flag_en_odd=0; } return true; } return false; } int read_char() { int x; for(;;) { x=getchar(); if(x=='\n'||x=='\r') continue; else return x; } } bool read_disk() { memset(RAID,0,sizeof(RAID)); for(int i=0;i<num_disk;i++) { for(int j=0;j<num_bit*num_block;j++) { RAID[j/num_bit][j%num_bit+i*64]=read_char(); } } return true; } void print_disk() { for(int i=0;i<num_block;i++) { for(int j=0;j<64*num_disk;j=j+64) { for(int k=0;k<num_bit;k++) { printf("%c",RAID[i][j+k]); } printf(" "); } printf("\n"); } printf("\n\n"); } bool is_valid() { for(int i=0;i<num_block;i++) { for(int j=0;j<num_bit;j++) { int cnt=0,pos,flag=0; for(int k=0;k<num_disk;k++) { if(RAID[i][k*64+j]=='x') { pos=k;//记录下x的位置,以便一会进行修改; cnt++; if(cnt==2) { return false; } } else { flag=(flag+RAID[i][k*64+j]-'0')%2;//进行运算 } } if(cnt==1) { if(flag_en_odd)//奇校验 { RAID[i][pos*64+j]=!flag+'0';//如果flag是0,那么应该改为1,如果flag是1,那么应该改成0 } else//偶校验 { RAID[i][pos*64+j]=flag+'0'; } } else//如果没有出现x { if(flag!=flag_en_odd) { return false;//说明不合理 } } } } return true; } char convert[]="0123456789ABCDEF"; //void comput() //{ // int pos=0,sum=0; // for(int pos_block=0;pos_block<num_block*num_disk;pos_block++) // { // if(pos_block%7==0) // { ////printf("%d\n",pos_block-(pos_block/num_disk)*num_disk); // continue;//跳过 // } // for(int i=0;i<num_bit;i++) // { // sum=sum*2+RAID[pos_block/num_disk][64*(pos_block%num_disk)+i]-'0'; // pos++;//计算了多少个数字了 // if(pos%4==0) // { // printf("%c",convert[sum]); // sum=0; // } // } // } // int flag=0; // while((pos%4)!=0) // { // flag=1; // sum=sum*2+0; // pos++; // } // if(flag) // { // printf("%c",convert[sum]); // } // printf("\n"); //} void comput() { int pos=0,sum=0; for(int i=0;i<num_block;i++) { for(int j=0;j<num_disk;j++) { if(j==i%num_disk) { //printf("block=%d disk=%d\n",i,j); //jump=0; continue; } for(int k=0;k<num_bit;k++) { sum=sum*2+RAID[i][64*j+k]-'0'; pos++;//计算了多少个数字了 if(pos%4==0) { printf("%c",convert[sum]); sum=0; } } } } int flag=0; while((pos%4)!=0) { flag=1; sum=sum*2+0; pos++; } if(flag) { printf("%c",convert[sum]); } printf("\n"); } int main() { #ifdef local freopen("input.txt","r",stdin); freopen("output1.txt","w",stdout); #endif int kase=0; while(initial()) { read_disk(); //print_disk(); if(is_valid()) { printf("Disk set %d is valid, contents are: ",++kase); comput(); //print_disk(); } else { printf("Disk set %d is invalid.\n",++kase); } //print_disk(); } return 0; }
还有一点就是,之前说的getchar()不能和其它的输入方式混合使用,说的是判定输入结果的条件是《空格或回车》,如果判定输入结束的条件不是这两个,而是其他的特殊字符或者给定的长度的话,那么可以使用read_char()函数。