笔试题10 -- 数组变换(通过乘2将所有数变相等)

数组变换(通过乘2将所有数变相等)

题目链接:数组变换__牛客网

原题复现

牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。问是否可行。

牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。

这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次。

数据范围:数组大小满足 1≤n≤50,数组中的数满足 1≤val≤10^9

输入描述:

输入一个正整数N (N <= 50)
接下来一行输入N个正整数,每个数均小于等于1e9.

输出描述:

假如经过若干次操作可以使得N个数都相等,那么输出"YES", 否则输出"NO"

示例:

输入

2
1 2

输出

YES

思路剖析

  1. 首先,我们假设这n个数经过变换满足所有数相等,考虑到既然每个数都进行了不同次数的乘2操作,那么最终得到的数肯定可以整除原数组中的每一个数,也可以被2所整除。

  2. 如果要使得他们在经历不同次乘2操作后值相等,那么初始数组中最小的数一定可以被其他所有数整除(或最大的数一定可以整除其他所有数)。因为如果最小数与其他数之间没有因数关系,那么最小数与其他数经过不同的2^n运算是始终无法相等的。如果每个数都满足该条件,那么最小数即为其他所有数的公共因数,可以进入下一步判断,否则判否。

  3. 检查数组中是否存在某个数e,使得 e/minval 为奇数。因为一旦最小数和某个数之间的倍数关系为非偶数,那么两者之间的转换倍数必定不可表示为2的n次方。这里考虑到c中的 ‘/’ 运算符,对于正数之间的运算存在向下取整,例如 3/2 = 1,但是只要发生取整转换,说明 e 和 minval 之间不满足整数倍关系,唯有通过条件 (2) 才能执行到这里,故此情况不存在。另外,由于避免数组中遍历到的值e和minval值相等,本来这轮遍历是满足条件的,但是 e/minval 的值是1 非偶数,所以对于 e/minval 计算到的值判断是否为偶数前先要保证它不等于1。(避免e和minval同值情况的误判)

  4. 数组中所有数都满足 (2)、(3) 的两个判断条件,那么返回true打印"YES",否则打印"No"。

示例代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n = 0;
    cin >> n;
    vector<int> v(n, 0);
    int minval = 1e9;
    bool flag = true;
    for(auto& e: v)
    {
        cin >> e;
        minval = min(e, minval);
    }

    for(auto e: v)
    {
        // 1.首先检查是否有元素不能被 min_val 整除
        if(e % minval != 0)
        {
            flag = false;
            break;
        }
        // 2.检查数组中是否存在e,使得e/minval为非偶数且不为1
        int x = e / minval;
        if(x != 1 && x % 2 != 0) { flag = false; break;}
    }
    if(flag)
    {
        cout << "YES" << endl;
    }
    else{
        cout << "NO" << endl;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

螺蛳粉只吃炸蛋的走风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值