CCF考试_损坏的RAID5_201903-3

参考网上

#include 
#include 
#include 
#include 
#include 

#define MAX_N 1010 // 最大硬盘数

using namespace std;

string disk[MAX_N];

inline char getc(char n){
	if(n <= 9){
		return n + '0';
	}else{
		return n - 10 + 'A';
	}
}

inline char getn(char ch){
	if(ch <= '9'){
		return ch - '0';
	}else{
		return ch - 'A' + 10;
	}
}

inline void _xor(string &s1, string s2){ // 用xor会和c++标准库函数冲突
	for(int i = 0; i < 8; i++){
		s1[i] = getc(getn(s1[i]) ^ getn(s2[i]));
	}
}

int main(){
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(false);
	int n, s, l; // 硬盘数,条带块数,行数
	cin >> n >> s >> l;
	int size_s = 8 * s; // 条带字符大小
	int block_cnt = 0;

	for(int i = 0; i < l; i++){ // 读取硬盘数据
		int cur_d; // 当前硬盘
		cin >> cur_d;
		cin >> disk[cur_d];
		if(i == 0){
			block_cnt = disk[cur_d].length();
		}
	}
	block_cnt *= (n - 1);
	block_cnt /= 8;

	int m; // 操作数
	cin >> m;
	for(int i = 0; i < m; i++){
		int a; // 块号
		cin >> a;
		int b = a / s, d = a - b * s; // 条带号和块中下标
		int k = b / (n - 1); // k
		int p = n - 1 - k % n; // 容错硬盘是哪个硬盘
		int c = (p + 1 + b - k *(n - 1)) % n; // 该块在哪个硬盘

		int beg = k * size_s + 8 * d; // 字符开始位置

		if(a >= block_cnt){
			cout << "-" << endl;
		}else if(disk[c].length() != 0){
			cout << disk[c].substr(beg, 8) << endl;
		}else{ // 该硬盘不存在数据
			if(l < n - 1){
				cout << "-" << endl;
			}else{
				string str = "00000000";
				for(int i = (c + 1) % n; i != c; i = (i + 1) % n){
					_xor(str, disk[i].substr(beg, 8));
				}
				cout << str << endl;
			}
		}
	}

	return 0;
}

自己写的

(如果把cin/cout都换成c标准in/out,甚至不用转换为字符数组再输出,还会超时???)

#include 
#include 
#include 

#define MAX_N 1010 // 最大硬盘数
#define STR_LEN 80 * 1024 + 10

typedef unsigned int BLOCK;

using namespace std;

char disk[MAX_N][STR_LEN];
bool disk_exist[MAX_N];

inline BLOCK getBlock(int idx, int beg){
	BLOCK block = 0;
	for(int i = beg; i < beg + 8; i++){
		block <<= 4;
		if(disk[idx][i] >= '0' && disk[idx][i] <= '9'){
			block += disk[idx][i] - '0';
		}else{
			block += disk[idx][i] - 'A' + 10;
		}
	}
	return block;
}

void toStr(char *s, BLOCK b){
	for(int i = 7; i >= 0; i--){
		unsigned char u = b % 0x10;
		b >>= 4;
		if(u <= 9){
			s[i] = u + '0';
		}else{
			s[i] = u - 10 + 'A';
		}
	}
}

int main(){
	freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(false);
	int n, s, l; // 硬盘数,条带块数,行数
	cin >> n >> s >> l;
	int size_s = 8 * s; // 条带字符大小
	int block_cnt = 0;

	for(int i = 0; i < l; i++){ // 读取硬盘数据
		int cur_d; // 当前硬盘
		cin >> cur_d;
		cin >> disk[cur_d];
		disk_exist[cur_d] = true;
		if(i == 0){
			block_cnt = strlen(disk[cur_d]);
		}
	}
	block_cnt *= (n - 1);
	block_cnt /= 8;

	int m; // 操作数
	cin >> m;
	for(int i = 0; i < m; i++){
		int a; // 块号
		cin >> a;
		int b = a / s, d = a - b * s; // 条带号和块中下标
		int k = b / (n - 1); // k
		int p = n - 1 - k % n; // 容错硬盘是哪个硬盘
		int c = (p + 1 + b - k *(n - 1)) % n; // 该块在哪个硬盘

		int beg = k * size_s + 8 * d; // 字符开始位置

		if(a >= block_cnt){
			cout << "-" << endl;
		}else if(disk_exist[c]){
			BLOCK block = getBlock(c, beg);
			char str[10] = "";
			toStr(str, block);
			cout << str << endl;
		}else{ // 该硬盘不存在数据
			if(l < n - 1){
				cout << "-" << endl;
			}else{
				int i = (c + 1) % n;
				BLOCK block = getBlock(i, beg);
				i++;
				for(; i != c; i = (i + 1) % n){
					block ^= getBlock(i, beg);
				}
				char str[10] = "";
				toStr(str, block);
				cout << str << endl;
			}
		}
	}
	return 0;
}

将自己写的转换为C语言,不超时但是慢很多???

#include 
#include 

#define MAX_N 1010 // 最大硬盘数
#define STR_LEN 80 * 1024 + 10

typedef unsigned int BLOCK;

char disk[MAX_N][STR_LEN];
int disk_exist[MAX_N];

BLOCK getBlock(int idx, int beg){
	BLOCK block = 0;
	int i;
	for(i = beg; i < beg + 8; i++){
		block <<= 4;
		if(disk[idx][i] >= '0' && disk[idx][i] <= '9'){
			block += disk[idx][i] - '0';
		}else{
			block += disk[idx][i] - 'A' + 10;
		}
	}
	return block;
}

void toStr(char *s, BLOCK b){
	int i;
	for(i = 7; i >= 0; i--){
		unsigned char u = b % 0x10;
		b >>= 4;
		if(u <= 9){
			s[i] = u + '0';
		}else{
			s[i] = u - 10 + 'A';
		}
	}
}

int main(){
	int n, s, l; // 硬盘数,条带块数,行数
	int size_s; // 条带字符大小
	int block_cnt = 0;
	int m; // 操作数
	int i;
	int cur_d; // 当前硬盘
	int a; // 块号
	int b, d; // 条带号和块中下标
	int k; // k
	int p; // 容错硬盘是哪个硬盘
	int c; // 该块在哪个硬盘
	int beg; // 字符开始位置
	BLOCK block;
	int j;

	freopen("in.txt", "r", stdin);

	scanf("%d%d%d", &n, &s, &l);
	size_s = 8 * s;

	for(i = 0; i < l; i++){ // 读取硬盘数据
		scanf("%d", &cur_d);
		scanf("%s", disk[cur_d]);
		disk_exist[cur_d] = 1;
		if(i == 0){
			block_cnt = strlen(disk[cur_d]);
		}
	}
	block_cnt *= (n - 1);
	block_cnt /= 8;

	scanf("%d", &m);
	for(i = 0; i < m; i++){
		scanf("%d", &a);
		b = a / s; 
		d = a - b * s; // 条带号和块中下标
		k = b / (n - 1); // k
		p = n - 1 - k % n; // 容错硬盘是哪个硬盘
		c = (p + 1 + b - k *(n - 1)) % n; // 该块在哪个硬盘

		beg = k * size_s + 8 * d; // 字符开始位置

		if(a >= block_cnt){
			printf("-\n");
		}else if(disk_exist[c]){
			block = getBlock(c, beg);
			printf("%08X\n", block);
		}else{ // 该硬盘不存在数据
			if(l < n - 1){
				printf("-\n");
			}else{
				j = (c + 1) % n;
				block = getBlock(j, beg);
				j = (j + 1) % n;
				for(; j != c; j = (j + 1) % n){
					block ^= getBlock(j, beg);
				}
				printf("%08X\n", block);
			}
		}
	}
	return 0;
}

 

超时,对比第一个,很奇怪

#include 
#include 
#include 
#include 
#include 

#define MAX_N 1010 // 最大硬盘数

using namespace std;

string disk[MAX_N];

inline char getc(char n){
	if(n <= 9){
		return n + '0';
	}else{
		return n - 10 + 'A';
	}
}

inline char getn(char ch){
	if(ch <= '9'){
		return ch - '0';
	}else{
		return ch - 'A' + 10;
	}
}

inline void _xor(string &s1, string s2){ // 用xor会和c++标准库函数冲突
	for(int i = 0; i < 8; i++){
		s1[i] = getc(getn(s1[i]) ^ getn(s2[i]));
	}
}

int main(){
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(false);
	int n, s, l; // 硬盘数,条带块数,行数
	scanf("%d%d%d", &n, &s, &l);
	int size_s = 8 * s; // 条带字符大小
	int block_cnt = 0;

	for(int i = 0; i < l; i++){ // 读取硬盘数据
		int cur_d; // 当前硬盘
		scanf("%d", &cur_d);
		char str[80 * 1200];
		scanf("%s", str);
		disk[cur_d] = str;
		if(i == 0){
			block_cnt = disk[cur_d].length();
		}
	}
	block_cnt *= (n - 1);
	block_cnt /= 8;

	int m; // 操作数
	scanf("%d", &m);
	for(int i = 0; i < m; i++){
		int a; // 块号
		scanf("%d", &a);
		int b = a / s, d = a - b * s; // 条带号和块中下标
		int k = b / (n - 1); // k
		int p = n - 1 - k % n; // 容错硬盘是哪个硬盘
		int c = (p + 1 + b - k *(n - 1)) % n; // 该块在哪个硬盘

		int beg = k * size_s + 8 * d; // 字符开始位置

		if(a >= block_cnt){
			printf("-\n");
		}else if(disk[c].length() != 0){
			printf("%s\n", disk[c].substr(beg, 8).c_str());
		}else{ // 该硬盘不存在数据
			if(l < n - 1){
				printf("-\n");
			}else{
				string str = "00000000";
				for(int i = (c + 1) % n; i != c; i = (i + 1) % n){
					_xor(str, disk[i].substr(beg, 8));
				}
				printf("%s\n", str.c_str());
			}
		}
	}

	return 0;
}

 

你可能感兴趣的:(算法题)