uva 509 Raid技术 紫书4-7
今天呀,本来是想去参加广工的新生网赛,1点到5点,特意准备的。但结果不知道杭电的oj参赛要提前报名,呃,进不去,只用过csu的oj,那好吧,就做紫书上的题吧。
初代程序完成了。大致思路是把输入的数据用二维数组存储起来,然后判断,如果有的行没有出现x,则效验结果应该正确,否则输出 磁盘非法,跳出循环。如果有一个x,则可以恢复,那就通过异或恢复x,如果两个x或以上,那无法恢复,输出磁盘非法跳出循环。
恢复后,按照四个比特的二进制转换为10进制并依此输出16进制结果。
第一次调试,发现自己的二维数组里的数据是getchar得来的,计算时应该减去’0’转换为原本的数字。
第二次调试,发现自己忽略了题目条件 如果数据不满4个比特则在后面加0。
第三次调试,发现自己虽然写了奇校验和偶校验变量,实际上有一种情况没有分类讨论,故出错了。
三次调试后通过样例输入,下面提交oa。
第一次wa,使用debug板块,看看哪里出错了.
debug板块给的两个样例,全过了,真不知道为什么wa。
经过自己仔细思考,发现犯了和象棋那题一样的错误。我的判断是如果到了最后一组,比特数还不足四位那就直接输出。可是有一种情况,最后一组如果是效验码呢?那效验码就被跳过了,最后还是会有一个数因为没满4比特而没有输出。于是我又加了个判断,如果这是倒数第二组数,而最后一组数是效验码,那么直接输出,无论满了四位没。
然后就ac啦。
大致思路就是存储,然后判断加复原。
复原后怎么输出结果呢?
每达到四个比特就输出一个十六进制,最后一组未达到则直接输出。由于题目要求16进制大写,所以要用%X来输出。
设disk1 disk2 disk3 这个是行,那disk1的内容就是列
用一个三重循环,第一层是列的递增,第二层是行的递增,第三层也是列,但是只要递增到了s个比特就结束第三层循环,换个磁盘继续加。
大致意思就是每个磁盘的一格有s个比特,s个比特加完了就加下一个磁盘。而这一行的磁盘的比特都加完了,就跳转到下一列,也就是磁盘的第二格,继续加,依此循环,每四位的二进制转换为10进制,并以%X输出。
然后怎么保证不输出校验码呢?加一个变量代表当前列数。该变量对磁盘个数取余数,得到的就是效验码所在的磁盘行数,加个if判断,如果该行不等于余数,才进行循环的计算。
下面放代码,没写注释,思路已经写在上面了。
#include<stdio.h>
#include<string.h>
#include<math.h>
int data[7][6500],d,s,b,kase=0,eo1,dd[6500],jj[6500];
int main()
{
freopen("input.txt","r",stdin);
while0:
while(scanf("%d%d%d",&d,&s,&b)==3&&d)
{ memset(data,0,sizeof(data));
memset(dd,0,sizeof(dd));
memset(jj,0,sizeof(jj));
char eo[2];
scanf("%s",&eo);
if(eo[0]=='E') eo1=0;
else if(eo[0]=='O') eo1=1;
getchar();
int sb=s*b;
for(int i=0;i<d;i++)
{
for(int j=0;j<sb;j++)
{
data[i][j]=getchar();
}
getchar();
}
for(int j=0;j<sb;j++)
{
for(int i=0;i<d;i++)
{
if (data[i][j]=='x'){dd[j]++;jj[j]=i;}
}
}
for (int j=0;j<sb;j++)
{
int c=eo1;
if (dd[j]==0)
{
for (int i=0;i<d;i++)
{
c=c^(data[i][j]-'0');
}
if (c!=0){printf("Disk set %d is invalid.\n",++kase);goto while0;}
}
else if(dd[j]==1)
{
for(int i=0;i<jj[j];i++)
{
c=c^(data[i][j]-'0');
}
for(int i=jj[j]+1;i<d;i++)
{
c=c^(data[i][j]-'0');
}
int unknow=jj[j];
data[unknow][j]=(c+'0');
}
else if(dd[j]>1){printf("Disk set %d is invalid.\n",++kase);goto while0;}
}
int count2=3,number=0;
printf("Disk set %d is valid, contents are: ",++kase);
int booll=0;
for (int j=0;j<sb;j=j+s)
{
for(int i=0;i<d;i++)
{
if(i!=booll%d){
for (int j1=j;j1<j+s;j1++)
{
number+=((data[i][j1]-'0')*pow(2,count2));
count2--;
if(j1==sb-1&&i==d-1){count2=-1;}
if(j1==sb-1&&i==d-2&&(i+1)==booll%d){count2=-1;}
if(count2==-1){printf("%X",number);number=0;count2=3;}
}
}
}
booll++;
}
printf("\n");
}
return 0;
}
加油哦!!!