• Justice(HDU6557+2018年吉林站+二进制)


    题目链接

    传送门

    题意

    给你(n)个数,每个数表示(frac{1}{2^{a_i}}),要你把这(n)个数分为两堆,使得每堆的和都大于等于(frac{1}{2})

    思路

    首先我们假设第一堆的下标为(x_1,x_2dots,x_n),且(2^{a_{x_1}}leq 2^{a_{x_2}}leqdotsleq 2^{a_{x_n}}),则:

    [egin{aligned} &sumlimits_{i=1}^{n}frac{1}{2^{a_{x_i}}}&\ =&sumlimits_{i=1}^{n}frac{2^{a_{x_n}-a_{x_i}}}{2^{a_{x_n}}} ext{(通分)}& end{aligned} ]

    我们知道(2)(2^x)构成一个(2^{x+1}),因此我们确定每一堆分母的最大值后按照(2^{a_{x_i}})从小到大来凑(2^{a_{x_n}-1})
    注意,一旦相邻两个数的大小差值大于等于(17)就直接不用取输出(NO),因为(2^{17}geq 10^5),后面不管怎么凑都是不可能凑出我们所需要的数的。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <cassert>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1e9 + 7;
    const int maxn = 1e5 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t, n;
    int vis[maxn];
    
    struct node {
        int val, id;
        bool operator < (const node& x) const {
            return val < x.val;
        }
    }a[maxn];
    
    int main() {
    #ifndef ONLINE_JUDGE
    FIN;
    #endif // ONLINE_JUDGE
        scanf("%d", &t);
        int icase = 0;
        while(t--) {
            scanf("%d", &n);
            for(int i = 1; i <= n; ++i) {
                scanf("%d", &a[i].val);
                a[i].id = i;
                vis[i] = 0;
            }
            printf("Case %d: ", ++icase);
            sort(a + 1, a + n + 1);
            LL nw;
            if(a[1].val == 1) {
                vis[a[1].id] = 1;
            } else {
                nw = a[1].val - 1;
                if(nw >= 17) {
                    printf("NO
    ");
                    continue;
                }
                nw = (1<<nw) - 1;
                vis[a[1].id] = 1;
                for(int i = 2; i <= n; ++i) {
                    if(nw == 0) break;
                    if(a[i].val == a[i-1].val) --nw, vis[a[i].id] = 1;
                    else {
                        if(a[i].val - a[i-1].val >= 17) {
                            break;
                        }
                        nw = nw * (1<<(a[i].val - a[i-1].val)) - 1;
                        if(nw > n - i) break;
                        vis[a[i].id] = 1;
                    }
                }
                if(nw != 0) {
                    printf("NO
    ");
                    continue;
                }
            }
            int idx = -1;
            for(int i = 1; i <= n; ++i) {
                if(!vis[a[i].id]) {
                    idx = i;
                    break;
                }
            }
            if(idx == -1) {
                printf("NO
    ");
                continue;
            }
            if(a[idx].val == 1) {
                printf("YES
    ");
                for(int i = 1; i <= n; ++i) {
                    printf("%d", vis[i]);
                }
                printf("
    ");
            } else {
                nw = a[idx].val - 1;
                if(nw >= 17) {
                    printf("NO
    ");
                    continue;
                }
                nw = (1<<nw) - 1;
                for(int i = idx + 1; i <= n; ++i) {
                    if(nw == 0) break;
                    if(vis[a[i].id]) continue;
                    if(a[i].val == a[i-1].val) --nw;
                    else {
                        if(a[i].val - a[i-1].val >= 17) {
                            break;
                        }
                        nw = nw * (1<<(a[i].val - a[i-1].val)) - 1;
                        if(nw > n - i) break;
                    }
                }
                if(nw != 0) {
                    printf("NO
    ");
                    continue;
                }
                printf("YES
    ");
                for(int i = 1; i <= n; ++i) {
                    printf("%d", vis[i]);
                }
                printf("
    ");
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    linux sort,uniq,cut,wc命令详解
    Linux IO实时监控iostat命令详解
    uniq命令
    四层和七层负载均衡的区别
    keepalived 和 heartbeat对比
    LVS+Keepalived实现负载均衡
    Lvs+heartbeat高可用高性能web站点的搭建
    使用 awk 过滤文本或文件中的字符串
    最全mysql的复制和读写分离
    伤不起
  • 原文地址:https://www.cnblogs.com/Dillonh/p/11201974.html
Copyright © 2020-2023  润新知