核💗: 陣列由n+1個磁盤組成,每一個磁盤由塊(8位字符串)組成,s個塊組成一個條帶. ios
咱們把每個磁盤的編號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)post
最後咱們將塊號x細化到第disk個磁盤的第start塊: start=x%s+k*s, 數據開始的位置_start=start*8性能
紅色標記表示爲k值測試
坑:spa
1.題目中所指出的「硬盤數據大小 40KiB」指的是原始數據的大小,不是測試集中給出的16進制字符串的大小。code
由於硬盤原始數據的長度是其對應16進製表示的字符串長度的1/2(不考慮空格)。若是採用靜態存儲類型的數組放置字符串,其元素個數不該少於3*40KiB。blog
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; }
——參考自網絡