饿饿 饭饭2 - 题目 - Daimayuan Online Judge
对于某一个孩子,他有一个球,球上有一个数字n代表了要给他的数字的个数,然后对于n个数,能否使得n个数字都变成相同的(通过对任意数乘2或乘3,无数次操作,无关顺序)
每个数都大于等于1,也就是说每个数只能变大,不能变小,那么要使得所有数都通过乘2或3的手段变成某一个很大的数
首先,因为无关顺序,可以先排序一下,从小到大排序
4 50 75 75 150
可以求出它们最小得变成的数,即最大的数和第二大的数和2和3的最小公倍数x,使得第二大的数和最大的数能变成一个相同的数
但是问题在于最大的数和最小的数相乘再乘2乘3可能会超出long long范围(后来想了想,不会超) long long范围9e18
然后对于所有数,如果可以通过乘1或乘2或乘3变成x,那么就输出YES,否则输出NO
这个方案似乎不行,可能最后两个数可以变成相同的数,比如4 5 5,5==>30,但是4不能变成30,但是5==>60,4就能变成60了,所以说我们根本不能确定最小得变成的数是多少,再变大就会超出long long范围了
往大了不行,那就往小了想,将其2,3的因子全部除掉,这样得到一个最简的数,若所有的数的最简数相同,那么就输出YES,否则输出NO
错误代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
signed main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n);
int x = (a[n - 1] * a[n - 2]) / gcd(a[n - 1], a[n - 2]);
x = (x * 2) / gcd(x, 2);
x = (x * 3) / gcd(x, 3);
bool flag = true;
for (int i = 0; i < n; i++) {
if (x % a[i] != 0) {
flag = false;
break;
}
else {
if (a[i] == x) continue;
int y = x/a[i];
if (y % 2 == 0 || y % 3 == 0) continue;
else {
flag = false;
break;
}
}
}
if (flag) puts("YES");
else puts("NO");
}
}
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
signed main()
{
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) {
int x = a[i];
while (x % 2 == 0 || x % 3 == 0) {
if (x % 2 == 0) x /= 2;
if (x % 3 == 0) x /= 3;
}
a[i] = x;
}
sort(a, a + n);
bool flag = true;
for (int i = 1; i < n; i++) {
if (a[i] != a[i - 1]) {
flag = false;
break;
}
}
if (flag) puts("YES");
else puts("NO");
}
}