真是没想到这道题还能被IO卡住。原本的做法是scanf”%8X”读,然后用getchar试探换行符。结果T。再试把试探删了,始终不行。最后放弃直接读Binary的想法,用的时候再做转换,直接读字符串进来。总算过了。
希望明天别遇上这么恶心的IO。今天晚上整理一下cstdio和iostream的格式化相关文档,明天考CSP使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <iostream> #include <iomanip> #include <cstdio> #include <vector> #include <string> #include <deque> #include <algorithm> #include <tuple> using namespace std; int n, s, l; vector<string> RAIDArray; int diskBlockCount; char buf[100]; void input(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n>>s>>l; RAIDArray.resize(n); for(int i=0;i<l;i++){ int diskID, data; int bCnt = 0; string s; cin>>diskID>>s; RAIDArray[diskID]=s; diskBlockCount = s.size() / 8; } } int RAID(int diskID, int localBlockID){ int data; sscanf((char *)&RAIDArray[diskID].c_str()[localBlockID*8],"%8X",&data); return data; } inline bool isDiskExists(int diskID){ return !RAIDArray[diskID].empty(); } inline int getGlobalStripeID(int blockID){ return blockID / s; } inline int getLocalStripeID(int globalStripeID){ return globalStripeID / (n-1); } inline int getlocalStripeECCDiskID(int localStripeID){ return n - 1 - localStripeID % n; } inline std::tuple<int, int> getLocalDiskAndBlockID(int blockID){ // Return Disk ID, Local Block ID int globalStripeID = getGlobalStripeID(blockID); int localStripeID = getLocalStripeID(globalStripeID); int localStripeECCDiskID = getlocalStripeECCDiskID(localStripeID); int localStripeDiskID = (localStripeECCDiskID + 1 + globalStripeID % (n-1)) % n; int localBlockID = localStripeID * s + blockID % s; return std::tuple<int, int>(localStripeDiskID, localBlockID); } inline std::tuple<bool, int> recoverDataDirect(int blockID){ int diskID, localBlockID; std::tie(diskID, localBlockID) = getLocalDiskAndBlockID(blockID); if(!isDiskExists(diskID)) return std::tuple<bool, int>(false, -1); else return std::tuple<bool, int>(true, RAID(diskID, localBlockID)); } inline std::tuple<bool, int> recoverDataECC(int blockID){ if(l < n-1) return std::tuple<bool, int>(false, -1); int diskID, localBlockID; int data = 0; std::tie(diskID, localBlockID) = getLocalDiskAndBlockID(blockID); for(int curDisk = 0;curDisk<n;curDisk++){ if(curDisk == diskID)continue; data ^= RAID(curDisk,localBlockID); } return std::tuple<bool, int>(true, data); } inline std::tuple<bool, int> recoverDataMain(int blockID){ int diskID, localBlockID; std::tie(diskID, localBlockID) = getLocalDiskAndBlockID(blockID); if(localBlockID >= diskBlockCount) return std::tuple<bool, int> (false, -1); bool flag; int result; std::tie(flag, result) = recoverDataDirect(blockID); if(flag) return std::tuple<bool, int> (flag, result); std::tie(flag, result) = recoverDataECC(blockID); if(flag) return std::tuple<bool, int> (flag, result); return std::tuple<bool, int> (false, -1); } void solve(){ int m, blockID; cin>>m; while(m--){ cin>>blockID; bool flag; int result; tie(flag, result) = recoverDataMain(blockID); if(!flag) cout<<"-\n"; else cout<<setw(8)<<setfill('0')<<hex<<uppercase<<result<<"\n"; } } int main(){ input(); solve(); } |