USACO Contact,难题,运算符重载,QuickSort,

我感觉是到目前为止最难的一题
参考消逝者的代码:http://www.nocow.cn/index.php/Code:USACO/contact/C%2B%2B
参考思路:http://www.nocow.cn/index.php/USACO/contact#.E7.AE.80.E6.98.93.E4.BD.86.E9.9D.9E.E5.B8.B8.E9.AB.98.E6.95.88.E7.9A.84.E6.96.B9.E6.B3.95

简易但非常高效的方法 消逝者

/* 
ID: wangxin12 
PROG: contact
LANG: C++ 
*/ 
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
#define MAX 999999999

int A, B, N;
int frequency[12][4100];
int transform, length;
int const_num[13] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };

class unit {
public:
	int frequency, length, num;
};

vector<unit> unit_pool;
string original_string;

void create_unit(int length, int num) {
	unit * u = new unit();
	u->frequency = frequency[length - 1][num];
	u->length = length;
	u->num = num;
	unit_pool.push_back(*u);
}

bool operator>(unit u1, unit u2) {
	if( (u1.frequency < u2.frequency) ||
		(u1.frequency == u2.frequency && u1.length > u2.length) ||
		(u1.frequency == u2.frequency && u1.length == u2.length && u1.num > u2.num) )
		return true;
	else
		return false;
}

template<typename T>
int partition(vector<T> &f, int start, int end) {
	T key = f[start];
	int left = start + 1, right = end;
	while(true) {
		while(left < right && f[right] > key) right--;
		while(left < right && key > f[left]) left++;
		if(left == right) break;
		T tmp = f[left];
		f[left] = f[right];
		f[right] = tmp;
	}

	if(f[left] > key) return start;
	f[start] = f[left];
	f[left] = key;
	return left;
}

template<typename T> 
void quick_sort(vector<T> &f, int start, int end) {
	if(start >= end) return;
	int boundary = partition(f,  start, end);
	quick_sort(f, start, boundary - 1);
	quick_sort(f, boundary + 1, end);
}

string transform_to_binary(int num, int length) {
	string s1 = "", s2 = "";
	int t = num;
	char tmp;
	while(t != 0) {
		s1 += (t % 2 + '0');
		t /= 2;
	}
	for(int j = s1.length() - 1; j >= 0; j--)
		s2 += s1[j];
	s1 = "";
	for(int i = 1; i <= length - s2.length(); i++) 
		s1 += '0';
	s1 = s1 + s2;
	return s1;
}

int main() {
	ifstream fin("contact.in");
	ofstream fout("contact.out");

	fin>>A>>B>>N;
	//original_string要一个char一个char的读入,否则读到换行符就停止了
	char ch;
	while(fin.get(ch)) {
		if(ch >= '0' && ch <= '1')
			original_string += ch;
	}

	//
	for(length = A; (length <= B) && (length <= original_string.size()); length++) {
		for(int start = 0; start <= original_string.length() - length; start++) 
		{
			transform = 0;
			for(int j = start; j <= start + length - 1; j++) //for使transform记载字符串大小
				if(original_string[j] == '1')
					transform += const_num[start + length - j - 1];
			frequency[length - 1][transform]++;
		}
	}

	for(int i = A; i <= B; i++) {
		for(int j = 0; j < const_num[i]; j++) {
			if(frequency[i - 1][j] != 0)
				create_unit(i, j);
		}
	}

	quick_sort(unit_pool, 0, (int)unit_pool.size() - 1);

	int last_frequency = 99999999, sum = 0, count = 0;
	for(int k = 0; k < unit_pool.size(); k++) {
		if(unit_pool[k].frequency < last_frequency) {
			sum++;
			if(sum == N + 1) break;
			if(k != 0) fout<<endl;
			count = 1;
			fout<<unit_pool[k].frequency<<endl;
			fout<<transform_to_binary(unit_pool[k].num, unit_pool[k].length);
			last_frequency = unit_pool[k].frequency;
		} else {
			count++;
			if(count == 7) {
				fout<<endl;
				count = 1;
			} else
			fout<<" ";
			fout<<transform_to_binary(unit_pool[k].num,unit_pool[k].length);
		}
	}

	fout<<endl;

	fin.close();
	fout.close();

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值