csp 201903-3 损坏的RAID5

问题描述
试题编号: 201903-3
试题名称: 损坏的RAID5
时间限制: 1.0s
内存限制: 512.0MB
问题描述:




答题栏
 
 

   核💗:  阵列由n+1个磁盘组成,每个磁盘由块(8位字符串)组成,s个块组成一个条带. 

              我们把每一个磁盘的编号disk看出纵坐标, 条带k看出横坐标.(所有磁盘的第一个条带k值相同),本题实质就是根据块号x查找(k,disk)的过程

              首先我们求出块x所在的条带号y:   y=x/s

    然后同一排有n个条带, 那么可以得出: k=y/n

              冗余条带的位置从第一排开始为从右往左,同一排的数据带编号紧跟冗余带从左往右, 那么第k排冗余带的位置 rd=n-k%(n+1), 那么第y条数据带的disk=(rd+y%n+1)%(n+1)

             最后我们将块号x细化到第disk个磁盘的第start块: start=x%s+k*s, 数据开始的位置_start=start*8

    

                                         红色标记表示为k值

坑:

1.题目中所指出的“硬盘数据大小 40KiB”指的是原始数据的大小,不是测试集中给出的16进制字符串的大小。

因为硬盘原始数据的长度是其对应16进制表示的字符串长度的1/2(不考虑空格)。如果采用静态存储类型的数组放置字符串,其元素个数不应少于3*40KiB。

 

2.本题具有大量I/O,容易在I/O消耗大量时间,造成超时。

std::ios::sync_with_stdio(false);
iostream默认是与stdio关联在一起的,以使两者同步,因此消耗了iostream不少性能。C++中的std :: cin和std :: cout为了兼容C,保证在代码中同时出现std :: cin和scanf或std :: cout和printf时输出不发生混乱,所以C++用一个流缓冲区来同步C的标准流。通过std :: ios_base :: sync_with_stdio函数设置为false后可以解除这种同步,让std :: cin和std :: cout不再经过缓冲区,iostream的性能就会提高了很多倍。

因此,当解除同步之后,注意不要与scanf、printf、puts等cstdio库中的输入输出函数混用以免出现问题。

 

#include<cstdio>
#include<iostream>
using namespace std;
const string base="0123456789ABCDEF";
const int N=1e3+5;
string d[N];int n,s,l,q,max_k;
inline int to_int(char c){
    if(c>='0'&&c<='9') return c-'0';
    return c-'A'+10;
}
inline void Xor(string &ans,string str){
    for(int i=0,x,y;i<8;i++){
        x=to_int(ans[i]);
        y=to_int(str[i]);
        ans[i]=base[x^y];
    }
}
string get_xor(int disk,int _start){
    string ans(8,'0');
    for(int i=0;i<=n;i++){
        if(i!=disk){
            Xor(ans,d[i].substr(_start,8));
        }
    }
    return ans;    
}
int main(){
    ios::sync_with_stdio(false);//使用string必加,or TLE 
    cin>>n>>s>>l;n--;//(n块数据,1块冗余)
    for(int i=0,id;i<l;i++){
        cin>>id;cin>>d[id];
//        cin>>id>>d[id];//不知道为什么错 
        max_k=d[id].size()/8/s;
    }
    cin>>q;
    for(int x,y,k,disk,sz,_start;q--;){
        cin>>x;
        y=x/s;
        k=y/n;
        disk=(n-k%(n+1)+y%n+1)%(n+1);
        sz=d[disk].size();
        if(k>=max_k) cout<<"-\n";
        else if(sz){
            _start=8*(x%s+k*s);
            cout<<d[disk].substr(_start,8)<<'\n';
        }
        else if(!sz&&l==n){
            _start=8*(x%s+k*s);
            cout<<get_xor(disk,_start)<<'\n';
        }
        else cout<<"-\n";
    }
    return 0;
}

 

——参考自网络

posted @ 2019-10-04 22:08  神犇(shenben)  阅读(453)  评论(2编辑  收藏  举报