1 条题解

  • 0
    @ 2025-4-7 19:49:26

    要解决这个齿轮比实现的问题,关键在于将机械传动的问题转化为数学上的质因数分解与覆盖问题。以下是详细的解题思路:

    问题分析

    齿轮传动比的计算规则是:总传动比等于各齿轮对传动比的乘积。若主动轮齿数为 C1 C_1 ,从动轮齿数为 C2C_2 ,则该齿轮对的传动比为 C1C2\frac{C_1}{C_2} 。整个系统的总传动比是各齿轮对传动比的乘积。

    核心思路

    1. 数学建模
      设目标传动比为 a:b a:b ,约分后为 pq \frac{p}{q} (其中 p=agcd(a,b) p = \frac{a}{\text{gcd}(a,b)} q=bgcd(a,b) q = \frac{b}{\text{gcd}(a,b)} )。
      齿轮组中每个齿轮的齿数可表示为 ci=c×ki c_i = c \times k_i ,其中 c c 是齿轮组的最小齿数,ki k_i 为整数(题目保证所有齿数是 c c 的倍数)。

    2. 质因数分解

      • p p qq 进行质因数分解,得到它们的质因数集合。
      • p p q q 的所有质因数都能由齿轮组的 kik_i 的质因数组合而成,则传动比可实现。

    具体步骤

    1. 预处理齿轮组

      • 找到最小齿数 c c ,计算每个齿轮的 ki=cic k_i = \frac{c_i}{c}
      • 收集所有 ki k_i 的质因数,形成可覆盖的质因数集合。
    2. 处理目标传动比

      • 计算 gcd(a,b) \text{gcd}(a,b) ,将 a:b a:b 约分为 pq \frac{p}{q}
      • q=0 q = 0 ,直接不可实现(但题目中b1 b \geq 1 ,故无需处理)。
    3. 质因数覆盖检查

      • 分解 p p 的质因数,检查每个质因数是否能被 kik_i 的质因数覆盖。
      • 分解 q q 的质因数,同样检查覆盖性。
      • p p q q 均满足覆盖条件,则传动比可实现。

    C++实现:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N = 64;
    const int M = 10010;
    const int INF = 1 << 30;
    
    int num[N], n, m, qa, qb;
    bool stat[M]; // 全局状态数组,标记可实现的齿轮比
    
    // 计算最大公约数(GCD)
    int gcd(int a, int b) {
    	return b == 0 ? a : gcd(b, a % b);
    }
    
    // 判断 qa:qb 是否可以由已有的齿轮比组合得到
    bool judge(int a, int b) {
    	for (int i = 1; i * a < M && i * b < M; ++i) {
    		if (stat[i * a] && stat[i * b]) {
    			return true;
    		}
    	}
    	return false;
    }
    
    // 预处理所有可能的齿轮比
    void pre() {
    	int i, j, tmp;
    	cin >> n;
    	int num_input[N]; // 使用固定大小的数组
    	
    	for (i = 0; i < n; ++i) {
    		cin >> num_input[i];
    	}
    	
    	// 收集所有可能的齿轮比(num[i]/num[j] 的约简形式)
    	int temp_fac[N * N]; // 临时存储因子
    	int top = 0;
    	
    	for (i = 0; i < n; ++i) {
    		for (j = 0; j < n; ++j) {
    			if (i == j) continue;
    			if (num_input[i] % num_input[j] == 0) {
    				temp_fac[top++] = num_input[i] / num_input[j];
    			}
    		}
    	}
    	
    	// 初始化 stat 数组
    	for (i = 0; i < M; ++i) {
    		stat[i] = false;
    	}
    	stat[1] = true; // 1:1 是基础比例
    	
    	// 动态规划计算所有可能的齿轮比
    	for (i = 0; i < top; ++i) {
    		int current_fac = temp_fac[i];
    		for (j = 1; j * current_fac < M; ++j) {
    			if (stat[j]) {
    				tmp = j * current_fac;
    				if (tmp < M) {
    					stat[tmp] = true;
    				}
    			}
    		}
    	}
    }
    
    int main() {
    	int testcase, testid, a, b;
    	cin >> testcase;
    	
    	for (testid = 1; testid <= testcase; ++testid) {
    		pre(); // 预处理当前测试用例的齿轮比
    		
    		cin >> m;
    		cout << "Scenario #" << testid << ":" << endl;
    		
    		while (m--) {
    			cin >> a >> b;
    			int d = gcd(a, b);
    			qa = a / d;
    			qb = b / d;
    			
    			if (judge(qa, qb)) {
    				cout << "Gear ratio " << a << ":" << b << " can be realized." << endl;
    			} else {
    				cout << "Gear ratio " << a << ":" << b << " cannot be realized." << endl;
    			}
    		}
    		
    		cout << endl; // 输出空行分隔测试用例
    		
    		if (testid < testcase) {
    			// 重置 stat 数组
    			for (int i = 0; i < M; ++i) {
    				stat[i] = false;
    			}
    		}
    	}
    	
    	return 0;
    }
    
    
    • 1

    信息

    ID
    396
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者