这道题很侥幸地过了。基本就是按照题目(comment)说的逻辑做的。主要优化在于判断最大的ratio至少是最小的ratio的3倍这一点上。由于ratio = F / R,那么我们知道最大的ratio=max(F)/min(R),同理可得最小的ratio。这样可以提前判断ratio那个条件,如果不成立就跳过,免去了求每个ratio和sort的过程。
一个不主要,但是很重要的优化是把保存ratio, diff的数组定义放在循环外面。因为他们都是固定大小的,所以可以声明一次,覆盖写。这样做之后所有测试样例都能过了,于是也懒得再尝试其他优化了。
/*
ID: thestor1
LANG: C++
TASK: cowcycle
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <climits>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
void kofrange_recur(int cur, int remaining, int high, vector<vector<int> > &combinations, std::vector<int> partial)
{
if (remaining == 0)
{
combinations.push_back(partial);
return;
}
for (int i = cur; i <= high - remaining + 1; ++i)
{
partial.push_back(i);
kofrange_recur(i + 1, remaining - 1, high, combinations, partial);
partial.pop_back();
}
}
std::vector<vector<int> > kofrange(int low, int high, int k)
{
vector<vector<int> > combinations;
kofrange_recur(low, k, high, combinations, std::vector<int>());
return combinations;
}
void printCombinations(vector<vector<int> > &combinations)
{
for (int i = 0; i < combinations.size(); ++i)
{
cout<<i<<":";
for (int j = 0; j < combinations[i].size(); ++j)
{
cout<<combinations[i][j]<<"\t";
}
cout<<endl;
}
}
int main()
{
FILE *fin = fopen("cowcycle.in", "r");
FILE *fout = fopen("cowcycle.out", "w");
int F, R;
int F1, F2, R1, R2;
fscanf(fin, "%d", &F);
fscanf(fin, "%d", &R);
fscanf(fin, "%d %d %d %d", &F1, &F2, &R1, &R2);
// cout<<F<<" "<<R<<endl;
// cout<<F1<<" "<<F2<<" "<<R1<<" "<<R2<<endl;
vector<vector<int> > combF = kofrange(F1, F2, F);
vector<vector<int> > combR = kofrange(R1, R2, R);
// printCombinations(combinations);
double minvariance = -1.0, minf = -1, minr = -1;
std::vector<double> ratios(F * R, 0.0);
std::vector<double> diff(F * R - 1, 0.0);
for (int f = 0; f < combF.size(); ++f)
{
for (int r = 0; r < combR.size(); ++r)
{
// combF[f]
// combR[r]
if (1.0 * combF[f][combF[f].size() - 1] / combR[r][0] < 3.0 * combF[f][0] / combR[r][combR[r].size() - 1])
{
continue;
}
for (int i = 0; i < combF[f].size(); ++i)
{
for (int j = 0; j < combR[r].size(); ++j)
{
// ratios.push_back(((double)combF[f][i]) / combR[r][j]);
ratios[i * R + j] = ((double)combF[f][i]) / combR[r][j];
}
}
sort(ratios.begin(), ratios.end());
// int nratios = ratios.size();
// cout<<"[debug]suggest:"<<1.0 * combF[f][combF[f].size() - 1] / combR[r][0]<<", "<<1.0 * combF[f][0] / combR[r][combR[r].size() - 1]<<endl;
// cout<<"[debug]reallly:"<<ratios[nratios - 1]<<", "<<ratios[0]<<endl<<endl;
// if (ratios[nratios - 1] < ratios[0] * 3)
// {
// continue;
// }
for (int i = 0; i < ratios.size() - 1; ++i)
{
// diff.push_back(ratios[i + 1] - ratios[i]);
diff[i] = ratios[i + 1] - ratios[i];
}
double sum = 0.0;
for (int i = 0; i < diff.size(); ++i)
{
sum += diff[i];
}
double mean = sum / diff.size();
sum = 0.0;
for (int i = 0; i < diff.size(); ++i)
{
sum += (diff[i] - mean) * (diff[i] - mean);
}
double variance = sum / diff.size();
if (minvariance < 0 || variance < minvariance)
{
minvariance = variance;
minf = f;
minr = r;
}
}
}
for (int i = 0; i < combF[minf].size(); ++i)
{
if (i != combF[minf].size() - 1)
{
fprintf(fout, "%d ", combF[minf][i]);
}
else
{
fprintf(fout, "%d\n", combF[minf][i]);
}
}
for (int i = 0; i < combR[minr].size(); ++i)
{
if (i != combR[minr].size() - 1)
{
fprintf(fout, "%d ", combR[minr][i]);
}
else
{
fprintf(fout, "%d\n", combR[minr][i]);
}
}
fclose(fin);
fclose(fout);
return 0;
}