uva 509 Raid技术 紫书4-7

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;
}

加油哦!!!

猜你喜欢

转载自blog.csdn.net/qq_43328498/article/details/84675835
509