试题ios
分析:
一、当l>=n-1时,全部数据才能够彻底读出
当l<n-1时,全部损坏的硬盘上的数据均没法读出
二、能够把8个字符(即四个字节、一个块)放进一个int中
三、询问编号为b的块在什么位置,即,编号为bs=b/s的条带在什么位置,b块位于该条带的第b%s块
四、下图的文字描述很是很差理解,但能够看图找规律c++
能够发现,不考虑校验条带的状况下,条带编号仍是从左往右,从上到下依次编号的,不过是有几个校验条带插了进去。
编号为bs的条带位于bs%n号硬盘上
考虑上校验磁带,bs的行号(图中的k)为ds/(n-1)(图中n=4)
五、再将一个条带表明s个块考虑进去
六、关于一个字符串长度,通过二分查找,我写的code的T至少要取到55(然而我也没算出来为啥是这个数git
七、加上O2编译吧,要否则正好卡在一秒上(CCF老爷机。。。:)
八、第二个测试点
3 2 2
0 000102030405060710111213141516172021222324252627
1 A0A1A2A3A4A5A6A7B0B1B2B3B4B5B6B7C0C1C2C3C4C5C6C7
2
2
5ide


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 }