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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM