我在这题卡了一天,心态有点小崩。不过最后AC的时候还是很开心的。
坑点:1.注意当两个及以上disc无法读取时,输入不合法。
???????????2.当校验结果与预期ans不同时,输入不合法。
???????????其它都为合法情况。
???????????当合法时,校验块不能作为数据读取,所以要判断磁盘储存区是否为校验块。
???????????最后将二进制转化为十六进制串时如比特数量不是4的整数,应当在ans串末尾补零。我采用string流和transform函数来进行进制转换,也可以用bitset。
? ? ? ? ? ? 原题:
????????
?
? ? ? ? ? ? 代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>//stringstream
#include<vector>//采用二维向量储存字符串
#include<iomanip>
using namespace std;
int main(void)
{
ios::sync_with_stdio(false);//关闭流同步
cin.tie(0);
cout.tie(0);
long long d,s,b,kase=1;
while(cin>>d&&d)
{
cin>>s>>b;
char parity;
cin>>parity;
vector<vector<string>> RAID;//模拟discset
RAID.clear();
string ANS="";//待定答案
long long cnt=0;
for(int i=0;i<b;i++)
{
vector<string> init(d,"");
RAID.push_back(init);
}//二维向量初始化
for(int i=0;i<d;i++)
{
string temp;
cin>>temp;
int k=0;
for(int j=0;j<s*b;j+=s)
{
RAID[k][i]=temp.substr(j,s);
k++;
}//对输入字符串切串储存在disc中
}
int ans;
bool flag=true;//判断输入是否合法
if(parity=='E')//偶校验
{
ans=0;
}
else//奇校验
{
ans=1;
}
for(int i=0;i<b;i++)//这里注意循环嵌套的次序
{
for(int k=0;k<s;k++)
{
int final=-10,pro=-10;//final存储异或结果,pro存储x位置
for(int j=0;j<d;j++)//对于每一层各data存段的第k个字符进行遍历
{
if(RAID[i][j][k]=='0')
{
if(final<0)
{
final=0;
}
else
{
final^=0;
}
}
else if(RAID[i][j][k]=='1')
{
if(final<0)
{
final=1;
}
else
{
final^=1;
}
}
else if(RAID[i][j][k]=='x')
{
if(pro<0)
{
pro=j;
}
else//如果在同一层同字节有超过一个x则非法
{
flag=false;
goto out;
}
}
}
if(pro>=0)//求x值
{
if(ans)
{
RAID[i][pro][k]=(!final)+'0';
final=1;
}
else
{
RAID[i][pro][k]=final+'0';
final=0;
}
}
else//无x时判断校验结果
{
if(ans!=final)
{
flag=false;
goto out;
}
}
}
}
for(int i=0;i<b;i++)
{
for(int j=0;j<d;j++)
{
if(j!=cnt)
{
ANS+=RAID[i][j];//查询答案序列
}
}
cnt++;
cnt%=d;
}
out:
cout<<"Disk set "<<kase++<<" is ";
if(flag)
{
cout<<"valid, contents are: ";
long long len=ANS.length();
while(len%4)//补0操作
{
ANS+="0";
len++;
}
for(int i=0;i<len;i+=4)//按每4个字符切串转进制
{
string sub,HEX;
sub=ANS.substr(i,4);
stringstream ss;
ss<<hex<<stoi(sub,nullptr,2);
ss>>HEX;
transform(HEX.begin(),HEX.end(),HEX.begin(),::toupper);
cout<<HEX;
}
cout<<endl;
}
else
{
cout<<"invalid."<<endl;
}
}
return 0;
}
|