题目描述如下:
一道蛮简单的题目,如果是高中生可能反应会更快。
可惜我是愚蠢的大学生。
给出n个齿轮,左边齿轮带动右边齿轮转动,问能否使右边的齿轮角速度为左边齿轮的q倍?
物理常识告诉我们,这些齿轮的线速度v 全都是相等的。
物理公式告诉我们,线速度v = 半径 r ✖️ 角速度 w。
当v固定的情况下,角速度与半径成反比,因此只需要看每个齿轮之间半径的倍数关系,便可以知道角速度之间的倍数关系。也就是说只有存在一个齿轮半径是另一个齿轮半径的q倍,那么输出结果就是YES。因此我们需要标记一下半径为 r 的齿轮是否存在,然后找他的q倍是否存在,即可得出 q 倍能否组装成功。
这时候来简单看一下数据范围,显然,我们直接开一个大小为2e5的数组来标记半径即可。当然,询问q 为 1的情况需要特别判断,毕竟一个齿轮不能当两个用。
//
//
// Created by MoonLight on 2023/6/7.
// 线速度 v 角速度 w 半径 r
// v = wr
// 线速度所有齿轮都相同,因此角速度只与半径有关
#include <iostream>
int n, Q;
int q, r;
int hasR[200010];
int canGet[200010];
using namespace std;
int main() {
cin >> n >> Q;
for (int i = 1; i <= n; i++) {
cin >> r;
hasR[r]++;
if (hasR[r] >= 2) {
canGet[1] = 1; // 如果相同半径的齿轮出现了不止1次,那么q = 1是可以满足的
}
}
for (int i = 1; i <= 200005; i++) {
if (hasR[i]) { // 有这个半径的齿轮,那么只要有他的倍数即可
for (int j = 2; i * j <= 200005; j++) { // 找倍数
if (hasR[i * j]) {
canGet[j] = 1;
}
}
}
}
for (int i = 1; i <= Q; i++) {
cin >> q;
if (canGet[q]) {
puts("YES");
} else {
puts("NO");
}
}
return 0;
}