我感觉是到目前为止最难的一题
参考消逝者的代码: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;
}