zoukankan      html  css  js  c++  java
  • foj 2044 1 M possible 二进制压缩

    题目链接:

    http://acm.fzu.edu.cn/problem.php?pid=2044

    题意:

     给出 一大堆数,找出2个出现次数模3 为1 的两个数字  

    题解:

    把一个数分为几位拆开统计,统计完后,把所有的位数都模三,这样剩下的数就为a和b的叠加了,但是信息丢失太多了,没有办法把a,b区分开。

    所以我们要多一个维护,在统计一个数对每一位的贡献的时候,同时统计任意两个位的联系的贡献(mp[i][j]++),这样最后把mp所有记录的联系都mod3剩下的就是a,b各自的联系了,这样就区分开了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int mp[32][32];
    int cnt[32],pos[32],tot;
    int main() {
        int tc,n,x,a,b,i,j,k,t;
        scanf("%d", &tc);
        while (tc--) {
            memset(cnt, 0, sizeof(cnt));
            memset(mp, 0, sizeof(mp));
            scanf("%d", &n);
            for (i = 0; i < n; i++) {
                scanf("%d", &x);
                tot = 0;
                for (j = 0; j < 31; j++) {
                    if (x&(1 << j)) {
                        pos[tot++] = j;
                        cnt[j]++;
                    }
                }
                for (j = 0; j < tot; j++) {
                    for (k = j + 1; k < tot; k++) {
                        mp[pos[j]][pos[k]]++;
                        mp[pos[k]][pos[j]]++;
                    }
                }
            }
            for (i = 0; i < 31; i++) cnt[i] %= 3;
            for (i = 0; i < 31; i++) {
                for (j = 0; j < 31; j++) {
                    mp[i][j] %= 3;
                }
            }
            a = 0;
            for (i = 0; i < 31; i++) {
                if (cnt[i]) {
                    cnt[i]--;
                    a ^= (1 << i);
                    for (j = 0; j < 31; j++) {
                        if (mp[i][j]) {
                            mp[i][j]--; mp[j][i]--;
                            cnt[j]--;
                            a ^= (1 << j);
                        }
                    }
                    break;
                }
            }
            b = 0;
            for (i = 0; i < 31; i++) {
                if (cnt[i]) b ^= (1 << i);
            }
            if (a > b) { t = a; a = b; b = t; }
            printf("%d %d
    ", a, b);
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET程序中常用的三十三种代码[低]
    IIS 6.0 优化
    JS判断数字字母中文
    javascript函数
    ASPJpeg和ASPUpload组件的一些属性和方法
    DOMDocument 的属性及一些javascript操作方法
    HTML/JS代码集合
    SEO常用工具站
    C#操作Word/excel文档
    高效的Session读写.
  • 原文地址:https://www.cnblogs.com/fenice/p/5533234.html
Copyright © 2011-2022 走看看