yzoj 2372 小B的数字 题解

题意

判断是否存在一个序列 $ b_i $ 使得 $ \prod_{i = 1}^{n} b_i ?| b_i^{a_i}$ 恒成立,其中 $ b_i $ 中的每个数都是2的正整数次幂。

样例输入

3
2
3 2
3
3 3 3
2
1 10

样例输出

YES
YES
NO

数据范围

对于 100% 的数据有 $ n \leq 10^5,a_i \leq 10,T \leq 10$

解析

首先拿到这道题,考场一看就知道不是规律题就是数学公式题,事实上是的。

我们可以设 $ b_i=2^{x_i} $ 其中 $ x_i \(为正整数,\) lcm(a_1,a_2,a_3....a_n)=LCM $ , $ sum=\sum_{i = 0}^{n} x_i?$。

那么我们可以将原式子化为 $ 2^{sum} | 2^{x_i * a_i} $,显然要使此式恒成立,就要满足 $ a_i * x_i \geq sum $.

此式子可以转化为 $ lcm* x_i \geq sum* \frac{lcm}{a_i} $

左右两边相加可得

$ lcm* sum \geq sum * ( \sum_{i = 1}^{n} {\frac{lcm}{a_i}}?)$

即 $ lcm \geq ( \sum_{i = 1}^{n} {\frac{lcm}{a_i}}?)$

两边提出 $ lcm $约去得到 $ 1 \geq ( \sum_{i = 1}^{n} {\frac{1}{a_i}}?)$

那么我们可以得出最终公式就是 $ ( \sum_{i = 1}^{n} {\frac{1}{a_i}}?\leq 1) $

如果我们直接同分比较,很显然会超数据范围。

对于这一题,由于涉及倒数,会产生浮点误差,我们有三种方法去处理

方法一(不推荐

在最终判断的时候设置精度进行调控

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-6;
int T,n,k;
bool cheak(double a,double b){
    if(a-b<=eps) return true;
    else return false;
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        double sum=0;
        for(int i=1;i<=n;++i){
            scanf("%d",&k);
            sum+=1.0/(double)k;
        }
        if(cheak(sum,(double)1)) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

方法二(正解

我们可以观察数据,可以知道 $ a_i \leq 10 $ 我们最终得到得式子也只与 $ a_i $ 得倒数有关,所以我们可以将式子改造,左右两边乘以 $ 10! $,也就是
$ ( \sum_{i = 1}^{n} {\frac{10!}{a_i}}?\leq 10!) $

于是运算便变为了整数运算,便不存在浮点误差了!(常用技巧)

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
typedef long long ll;
int main(){
   int t;
   scanf("%d",&t);
   while (t--){
       int n;
       scanf("%d",&n);
       ll tot=0;
       for(int i=0;i<n;i++){
           int x;
           scanf("%d",&x);
           tot+=3628800/x;
       }
       puts(tot<=3628800 ? "YES" : "NO");
   }
   return 0;
}

方法三(巧妙的暴力

分析式子 $ ( \sum_{i = 1}^{n} {\frac{1}{a_i}}?\leq 1) $ 我们可以发现如果 $ n > max(a_i) $ 那么这个式子必然不成立,所以我们可以把n的范围缩小到 $ max(a_i) $ 以内,那么我们通分就不会超出范围了于是便有了一个愉快的暴力

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    scanf("%d",&t);
    while (t--){
        int n;bool flag=1;
        scanf("%d",&n);
        long long tot=0;
        long long pop=1;
        int maxn=0;
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            maxn=max(maxn,x);
            if(x==1) flag=0;
            tot+=x;
            pop*=x;
        }
        if(!flag || n>maxn) printf("NO\n");
        else puts(tot<=pop ? "YES" : "NO");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/donkey2603089141/p/11663671.html

时间: 2024-07-31 13:25:30

yzoj 2372 小B的数字 题解的相关文章

python写的第一个简单小游戏-猜数字

1 #Filename:game1.py 2 3 guess=10 4 running=True 5 while running: 6 try: 7 answer=int(raw_input('Guess what i think:')) 8 except: 9 print 'Please input interga\n' 10 continue 11 12 if answer<guess: 13 print 'Your answer is too small\n' 14 continue 15

小凸玩密室题解

小凸玩密室题解 恶心题啊-- 开始连题意都看不懂, 看了会题解的题意简化,结果理解错了题意,说多了都是泪啊- 首先说说题意吧: 点亮一盏灯后,只有点亮完子树内所有灯后才能点其他灯,而且点亮的灯要求要连通. -->下一步一定点两个儿子之一,先点完这个儿子的子树再点另一个儿子. 然而,上一盏灯点什么十分不好求,贡献算不出(一个点子树内有多个层数相同的子孙). 但是,我们可以通过上一盏灯算下一盏灯的贡献啊(每个点只有一个层数一定的父辈). 所以点完这个点后,我们只有两种情况: 1.我们点完这个点后构成

小游戏-猜数字

效果图: 游戏说明: 浏览器随机生成0-100以内的一个数字,在输入框中填写你猜测的数字,猜测范围是0-100以内的正整数哦! 有十次机会猜测,且在这十次猜测中都会对每次的猜测数字进行提示.. 代码 html 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>猜数字小游戏</title>

小程序调取数字键盘,没有小数点解决办法

input框 有type属性这个大家都知道:比如text number  checkbox等常用的type值: 当type为number时,在小程序里调取的数字键盘是没有小数点的:应该改为:digit(哈哈,我自己开发的时候也没有注意这个): 下面简单记录一下 number:数字键盘(无小数点) idcard:数字键盘(无小数点.有个 X 键) digit:数字键盘(有小数点)注意:number 是无小数点的,digit 是有小数点的 原文地址:https://www.cnblogs.com/y

我的第一个Apple Watch小游戏——猜数字(Swift)

这是一个在AppleWatch上实现的一个小型App,开发语言为Swift.是一个猜数字的游戏,屏幕上会出现不同数字的滚动,并能控制游戏的开始结束,让别人来猜数字.是不是很有意思.还可以多个人来玩这个游戏,比大家谁最后的数字大. 该应用我已经上传至 https://github.com/chenyufeng1991/GuessNumber   . 由于该应用我主要是在Watch上实现的,所以在手机上不会有任何的效果,只会有一个白色的界面而已.实现步骤如下: (1)新建一个iOS中的Apple W

剑指offer 面试题8:旋转数组的最小数字 题解

面试题8:旋转数组的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个已从小到大排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.(要求不能直接遍历数组来求解.) 提交网址: http://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159 或 http:

BZOJ4568:[SCOI2016]幸运数字——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=4568 https://www.luogu.org/problemnew/show/P3292 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征. 一些旅行者希望游览 A 国.旅行者计划乘飞机降落在 x 号城市,沿着 x 号城市到 y 号城市之间那条唯一的路径游览,最终从 y

微信小程序——购物车数字加减

上一篇,我们有讲到如何造一个购物车弹层.今天来说一下,购物车数量的加减如何实现. 主要思路就是在data里面定义一个属性,属性值就是这个数量.点击+的时候就+1,点击-的时候就-1,再结合setData更改这个数字.当数字等于1的时候,要给-的按钮添加一个disabled的属性. wxml代码: <view class='row item-center'> <button class="buy-num-btn btn-minus" disabled="{{m

P2034选择数字题解

题目链接:在这里- 题目描述: 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入格式: 第一行两个整数n,k 以下n行,每行一个整数表示a[i]. 输出格式: 输出一个值表示答案. 思路:考虑反面,不能有超过k个连续的数字被选,等价于连续的k+1个数字中必须删一个,考虑如何去删数字,f[i]表示删了第i个数字的最小代价,f[i]可由(i-k-1)--->(i-1)转移过来,即在i前面的k+1个数字间,