zoukankan      html  css  js  c++  java
  • 2019牛客多校第四场D-triples I 贪心

    D-triples

    题意

    给你一个(n),问至少有几个数或运算起来可以等于(n),并且输出数量和这个几个数。题目说明给的(n)一定符合条件(不会输出(n= 1) 之类不存在情况)。

    思路

    • 我们打个表就能知道n至少可以由(1)个或者(2)个数或起来。

    • 首先我们预先判断(n \% 3 == 0)这种输出(n)自己本身就可以了

    • 其它的数可以由(2)个数进行或运算得到。

      1. (n)转换为二进制,把每一位上1提取出来放到集合(R)
      2. 找到两个集合(a、b)(acup b = R)
        (num1 = sum_{i=0}^{a.size()} x_{i} (x_{i}in a))
        (num1 \% 3 == 0)
        (num2 = sum_{i=0}^{b.size()} y_{i} (y_{i}in b))
        (num2 \% 3 == 0)
      3. 再分别把(a、b)集合里的数加起来就是答案了。

    样例(解决WA到哭的两个样例)

    2
    85
    682
    (1010101、1010101010)上面两个样例的二进制
    

    AC代码

    #include<bits/stdc++.h>
    #define mes(a, b) memset(a, b, sizeof a)
    using namespace std;
    typedef long long ll;
    int a[100];
    int ans[3];
    
    void solve(ll x){	//转换n为二进制
        int i = 0;
        while(x){
            a[i++] = x%2;
            x /= 2;
        }
    }
    int main(){
        int t;
        ll n;
        scanf("%lld", &t);
        while(t--){
            scanf("%lld", &n);
            if(n % 3ll == 0){
                printf("1 %lld
    ", n);
                continue;
            }
            mes(a, 0);
            solve(n);
            ans[1] = ans[2] = 0;	//分别计算二进制位为1的数字取模3分别为1和2的数量
            for(int i = 0; i <= 64; i++){
                if(a[i] == 1){
                    int num = (1ll<<i)%3ll;
                    ans[num]++;
                }
            }
            int sum = ans[1] + ans[2]*2;
            int b[3][3];
            mes(b, 0);
            if(sum % 3 ==1){	//强行分组(本人比较菜只会这样写)
                if(ans[1] == 0){
                    b[1][1] = 0;
                    b[1][2] = ans[2] - 2;
                    b[2][1] = 0;
                    b[2][2] = 3;
                }
                else{
                    b[1][1] = ans[1]-1;
                    b[1][2] = ans[2];
                    if(ans[2] == 0){
                        b[2][1] = 3;
                    }
                    else{
                        b[2][1] = 1;
                        b[2][2] = 1;
                    }
                }
            }
            else if(sum %3 == 2){
                if(ans[2] == 0){
                    b[1][1] = ans[1]-2;
                    b[1][2] = 0;
                    b[2][1] = 3;
                    b[2][2] = 0;
                }
                else{
                    b[1][1] = ans[1];
                    b[1][2] = ans[2]-1;
                    if(ans[1] == 0){
                        b[2][1] = 0;
                        b[2][2] = 3;
                    }
                    else{
                        b[2][1] = 1;
                        b[2][2] = 1;
                    }
                }
            }
            ll num1 = 0, num2 = 0;
            for(int i = 0; i < 64; i++){
                if(a[i] == 1){
                    int num = (1ll<<i)%3;
                    if(b[2][num] == ans[num]){
                        num2 += (1ll<<i);
                        b[2][num]--;
                    }
                    if(b[1][num] > 0){
                        num1 += (1ll<<i);
                        b[1][num]--;
                    }
                    ans[num]--;
                }
            }
            printf("2 %lld %lld
    ", num1, num2);
        }
        return 0;
    }
    
  • 相关阅读:
    如何在一个页面调用另一个页面
    CSS3新增的选择器和属性
    js中函数和方法的区别
    jQuery中哪几种选择器
    关于JS数组的栈和队列操作
    HDU1232 畅通工程(并查集)
    并查集
    有关素数的基础算法
    二分教室
    蚂蚁下桥(思维)
  • 原文地址:https://www.cnblogs.com/zhuyou/p/11261305.html
Copyright © 2011-2022 走看看