ccfcsp认证201903-3 损坏的RAID5

试题



分析:
1、当l>=n-1时,所有数据才可以完全读出
当l<n-1时,所有损坏的硬盘上的数据均无法读出
2、可以把8个字符(即四个字节、一个块)放进一个int中
3、询问编号为b的块在什么位置,即,编号为bs=b/s的条带在什么位置,b块位于该条带的第b%s块
4、下图的文字描述非常不好理解,但可以看图找规律


可以发现,不考虑校验条带的情况下,条带编号还是从左往右,从上到下依次编号的,不过是有几个校验条带插了进去。
编号为bs的条带位于bs%n号硬盘上
考虑上校验磁带,bs的行号(图中的k)为ds/(n-1)(图中n=4)
5、再将一个条带代表s个块考虑进去
6、关于一个字符串长度,经过二分查找,我写的code的T至少要取到55(然而我也没算出来为啥是这个数


7、加上O2编译吧,要不然正好卡在一秒上(CCF老爷机。。。:)
8、第二个测试点
3 2 2
0 000102030405060710111213141516172021222324252627
1 A0A1A2A3A4A5A6A7B0B1B2B3B4B5B6B7C0C1C2C3C4C5C6C7
2
2
5

 

 1 #pragma GCC optimize(2)
 2 #include<bits/stdc++.h>
 3 
 4 const int N=1025;
 5 const int T=60;
 6 int n,s,l;
 7 char a[N*T];
 8 int r[N][T*N];
 9 int len;
10 int bo[N];//bo[i]为真,第i个硬盘数据是否完整(从零开始编号。。。:)
11 int m,b;
12 int make(char* k){//将从字符k开始的八个字符压进一个int中
13     int ans=0;
14     for(int i=0;i<8;++i){
15         ans<<=4;
16         ans|=(isdigit(k[i])?k[i]-'0':k[i]-'A'+10);
17     }
18     return ans;
19 }
20 
21 void output(int db,int x){//输出第db块硬盘的第x块的内容
22     int k=r[db][x];
23     char s[8];
24     int t;
25     for(int i=0;i<8;++i){
26         t=(k&((1<<4)-1));
27         s[i]=t>9?t-10+'A':t+'0';
28         k>>=4;
29     }
30     for(int i=7;i>=0;--i)
31         std::cout<<s[i];
32     std::cout<<'\n';
33 }
34 int main(){
35     //freopen("in.txt","r",stdin);
36     std::ios::sync_with_stdio(false);
37     std::cin>>n>>s>>l;
38     int tmp;
39     for(int i=1;i<=l;++i){
40         std::cin>>tmp>>a;
41         if(!len)len=strlen(a);
42         for(int j=0;j<len;j+=8)
43             r[tmp][j>>3]=make(a+j);
44         bo[tmp]=true;
45     }
46     len/=8;
47     if(l==n-1){//如果只有一个硬盘损坏,利用其它n-1块硬盘恢复他,,,这样做邮电浪费时间。。。
48         int fa;
49         for(int i=0;i<n;++i)if(!bo[i]){fa=i;break;}
50         for(int j=0;j<len;++j)
51         for(int i=0;i<n;++i)
52             if(i!=fa)
53                 r[fa][j]^=r[i][j];
54         bo[fa]=true;
55     }
56     int bs,db;
57     long long t;
58     std::cin>>m;
59     for(int i=1;i<=m;++i){
60         std::cin>>b;
61         bs=b/s;
62         db=b/s%n;
63         t=(long long)bs/(n-1)*s+b%s;//担心爆int
64         if(t>=len||!bo[db]){std::cout<<"-\n";continue;}//t不能等于len,从0开始编号。。。:)
65         output(db,t);
66     }
67     return 0;
68 }
View Code

 

转载于:https://www.cnblogs.com/dashuai009/p/11151487.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值