牛客练习赛72 A brz的杯子 思维+二进制数

思维+二进制数brz的杯子

解题思路

这我是真没想到题目的 y ∣ x y∣x yx 意思是 x x x 可以被 y y y 整除…

那么问题意思就是:第 x x x 个杯子里的数要比它的因子 y y y 对应的杯子里的数大。

可以举个例子,比如现在 n n n 9 9 9

如果 x x x 8 8 8,因子有 2 , 4 2, 4 2,4,假设编号 1 1 1 的杯子里放的数是 1 1 1(从最小的开始枚举),那么编号 2 , 4 , 8 2, 4, 8 2,4,8 的杯杯就得分别放 2 , 3 , 4 2,3,4 2,3,4

如果 x x x 9 9 9,因子有 3 3 3,那么编号 3 3 3 的杯杯要比编号 1 1 1 的杯的数大,所以放 2 2 2

从上面的分析可以看出,至少需要 4 4 4 个数,所以 m > = 4 m >= 4 m>=4 就满足条件了。

我们只要去找 2 2 2 的次方的个数就行了。我做的时候是去找不大于 n n n 2 i 2^i 2i,统计个数,与 m m m 比较即可。

之后看了别人的题解,发现可以更简单,即判断 n n n 二进制的位数。妙啊~

参考代码

#include<bits/stdc++.h>
using namespace std;
//#define LOCAL  //提交的时候一定注释
#define _for(i, a, b) for(int i = (a); i < (b); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pb push_back
#define VI vector<int>
#define INF 0x3f3f3f3f
#define mp make_pair
typedef long long LL;
typedef double db;
const double eps = 1e-6;  //定义浮点数误差
const int MOD = 998244353;
const LL maxn = 1e9 + 10;

int readint(){
    
    
    int x; scanf("%d", &x); return x;
}

int main() {
    
    
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int t, ans, n, m;
    scanf("%d", &t);
    bool flag = false;  //flag记录是否是进行第一个查询
    _rep(i, 1, t) {
    
    
        scanf("%d%d", &n, &m);
        int cnt = 0;
        bool yes = true;  //yes记录是否能有方案
        for(int j = 1; (j << 1) <= n; j <<= 1) cnt++;  //统计需要的数字个数,从j=1开始,包括了编号为1的杯子
        if (cnt >= m) yes = false;
        
        if (!flag) {
    
      //第一个查询结果先保存,之后直接计算异或和
            ans = yes ? i : i - 1;
            flag = true;
        }
        else
            ans ^= (yes ? i : i - 1);cpp
    }
    printf("%d", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Encore47/article/details/109542061
今日推荐