USACO 6.3.3 Cowcycles 暴力

本文解析了一道USACO编程题,该题要求通过枚举方式选择齿轮组合实现特定传动比条件,并使传动比方差最小。文章提供了解题思路及C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://train.usaco.org/usacoprob2?a=lQZ5UB8ZNRK&S=cowcycle

题目大意:选出两组齿轮(数量分别不超过5个和10个),设前后轮齿数比为传动比,要求:1、最大传动比至少要是最小传动比的三倍    2、将传动比排序后相邻两者差(difference)的方差要最小


USACO总是出人意料,我原本以为会是一道超难的数学题或者构造题,再不济也得有个很酷的剪枝或是很厉害的规律,结果就是枚举尝试,还不如第一章里的虫洞。。。


/*
ID: frontie1
TASK: cowcycle
LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int F, R;
int f_st, f_ed, r_st, r_ed;
int f_gear[15], r_gear[15];
int f_output[20], r_output[20];
double output_var = 0x3f3f3f3f, tem_var;
double arr[100];
double dif[100];
int e = 0;
double total;

void DFS_r(int dep, int st, int ed)
{
    if(dep == R){
        //cout << "judge1 start" << endl;
        if(3*f_gear[0]*r_gear[0] > f_gear[F-1]*r_gear[R-1]) return;

        //cout << "get" << endl;
        e = 0; total = 0;
        for(int i = 0; i < F; ++i){
            for(int k = 0; k < R; ++k){
                arr[e++] = (double)f_gear[i] / r_gear[k];
            }
        }
        sort(arr, arr+e);
        for(int i = 1; i < e; ++i){
            dif[i] = (arr[i]-arr[i-1]);
            total += dif[i];
        }
        total /= (e-1);
        tem_var = 0;
        for(int i = 1; i < e; ++i){
            tem_var += (dif[i] - total) * (dif[i] - total);
        }
        if(tem_var < output_var){
            output_var = tem_var;
            for(int i = 0; i < F; ++i){
                f_output[i] = f_gear[i];
            }
            for(int i = 0; i < R; ++i){
                r_output[i] = r_gear[i];
            }
        }
        return;
    }
    else if(st > ed) return;
    else{
        for(int i = st; i <= ed; ++i){
            r_gear[dep] = i;
            DFS_r(dep+1, i+1, ed);
        }
    }
}

void DFS_f(int dep, int st, int ed)
{
    if(dep == F){
        //cout << "R start" << endl;
        DFS_r(0, r_st, r_ed);
        return;
    }
    else if(st > ed) return;
    for(int i = st; i <= ed; ++i){
        f_gear[dep] = i;
        DFS_f(dep+1, i+1, ed);
    }
}

int main()
{
    freopen("cowcycle.in", "r", stdin);
    freopen("cowcycle.out", "w", stdout);

    cin >> F >> R;
    cin >> f_st >> f_ed >> r_st >> r_ed;

    DFS_f(0, f_st, f_ed);

    for(int i = 0; i < F; ++i){
        cout << f_output[i];
        if(i != F-1) cout << ' ';
        else cout << endl;
    }

    for(int i = 0; i < R; ++i){
        cout << r_output[i];
        if(i != R-1) cout << ' ';
        else cout << endl;
    }

    return 0;
}

悄悄去看了USACO官方题解,原来还能哈希提速的,但是不想细看了,没有需求就没有动力(笑)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值