HDU 3972 1 M possible(思维)

1 M possible

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 2048/1024 K (Java/Others)

Total Submission(s): 1031    Accepted Submission(s): 343

Problem Description

There are 3*N+2 nonnegative integers. Except two special integers, the rest 3*N integers can form N triple groups: { Vi, Vj, Vk| Vi=Vj=Vk}, each integer are at most in one triple group.

Your task is to find the two special integers.

Now, suneast is so boring. He wants to compete with you. As there is no computer available for him, he has to find the integers use his eyes! Unbelievable! So just for fairness, your program can access ONLY 1MB memory!

Tips: Impossible itself says 1 M possible ------ Tourist’s quote (a topcoder target member)

Input

The first line of the input contains an integer T(T<=3), indicating the number of test cases.

Each case begin with a line containing an integers N(2<=N<=300000, N=2(mod3) ).

The second lines contains N nonnegative integers Vi (1<=Vi<=2147483647).

Output

For each test case, print a line containing two integers a, b (a<=b) separate by a blank. a, b is the desire two special integers.

Sample Input

2
2
1 2
23
1 3 1 4 5 2 1 1 3 1 4 5 2 1 1 3 1 4 5 2 1 2 1

Sample Output

1 2
1 2

题目大意:意思很简单,有3*n+2个数,有3*n个数都是三个三个一起出现的,找出剩下的两个数,不过空间只给了1M,可以算下只能开262144个int。不能直接保存。

解题思路:有同学直接是用hash,然后一次散列就可以做。大概一个月前的题目,比赛的时候就想过压缩成进制来做,不过当时想的是三进制,其实二进制更好解决这个问题。其他的都是%3==0,所以只用看最后两个数就可以了,那么如何知道位与位对应关系,我开了一个mp[32][32]的数组来记录位与位对应的关系,如果一个位唯一确定了一个数字,那么直接找其他位与这位有关系的位即可。详见代码。

题目地址:1 M possible

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;

int cnt[32],pos[32],mp[32][32];

void solve(int x)
{
    int i,j;

    int t=0,p=0;
    while(x)
    {
        if(x&1)
        {
            cnt[p]++;
            pos[t++]=p;
        }
        p++;
        x>>=1;
    }

    for(i=0;i<t;i++)
        for(j=i+1;j<t;j++)
            mp[pos[j]][pos[i]]++;
}

int main()
{
    int tes,n;
    int i,j,x;
    scanf("%d",&tes);

    while(tes--)
    {
        scanf("%d",&n);
        memset(cnt,0,sizeof(cnt));
        memset(pos,0,sizeof(pos));
        memset(mp,0,sizeof(mp));

        while(n--)
        {
            scanf("%d",&x);
            solve(x);
        }

        for(i=0;i<32;i++)
        {
            cnt[i]%=3;
            for(j=0;j<32;j++)
                mp[i][j]%=3;
        }

        int res1,res2;
        res1=res2=0;

        int poi=-1;
        for(i=31;i>=0;i--)
        {
            res1=res1*2;
            if(cnt[i]==2)
            {
                cnt[i]--;
                res1+=1;
            }
            else if(cnt[i]==1&&poi==-1)
            {
                cnt[i]--;
                poi=i;
                res1+=1;
            }
            else if(cnt[i]==1&&mp[poi][i]==1)
            {
                cnt[i]--;
                res1+=1;
            }
        }

        for(i=31;i>=0;i--)
        {
            res2=res2*2;
            if(cnt[i])
            {
                res2+=1;
            }
        }

        if(res1>res2)
        {
            int tmp=res1;
            res1=res2;
            res2=tmp;
        }
        printf("%d %d\n",res1,res2);
    }
    return 0;
}

/*
5
111 111 111 234 5453

328MS	232K
*/

HDU 3972 1 M possible(思维)

时间: 2024-11-03 05:40:53

HDU 3972 1 M possible(思维)的相关文章

HDU 6154 CaoHaha&#39;s staff 思维 找规律

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6154 题目描述: 围成一个面积不小于S的多边形, 最少需要多少根儿线段, 线段可以为单元格边或者对角线 解题思路: 最大的面积肯定是由根号2为边长的正方形围成了, 那么我们把所有正方形都遍历一遍, 找出S介于N, N+1的那个上界N+1设为max, 因为MAX所围成的多边形面积和MAX-1, MAX-2, MAX-3围成的多边形面积, 找出满足条件的最小的一个即可 代码: #include <io

2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6154 CaoHaha&#39;s staff 思维

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6154 题意:在笛卡尔坐标系下,画一个面积至少为  n 的简单多边形,每次只能画一条边或者一个格子的对角线,问至少要画几条. 解法:如果一个斜着的矩形长宽分别是 a,b,那么它的面积是 2ab.最优解肯定是离 sqrt(n/2)很近的位置.想想 n=5 时答案为什么是7 然后在那个小范围内枚举一下就好了.我给一张做题时画的图 #include <bits/stdc++.h> using namesp

hdu 4710 Balls Rearrangement (数学思维)

题意:就是  把编号从0-n的小球对应放进i%a编号的盒子里,然后又买了新盒子, 现在总共有b个盒子,Bob想把球装进i%b编号的盒子里.求重置的最小花费. 每次移动的花费为y - x ,即移动前后盒子编号的差值的绝对值. 算法: 题目就是要求                  先判断  n与  lcm(a,b)的大小,每一个周期存在循环,这样把区间缩短避免重复计算. 如果n>lcm(a,b)则   ans = (n/lcm)*solve(lcm)+solve(n%lcm) 否则   ans =

HDU 4869 Turn The Pokers 思维+组合

HDU 4869题意:m张牌,朝上状态为1,朝下状态为0,现在有n个操作 第i次操作可以反转任意xi张牌初始牌全部朝下,n,m<=1e5,问n次操作后能得到多少种不同的状态? 关心的是最后的状态 假如1有x个 则贡献C(m,x)种状态因为每翻转一次,1的个数和0的个数都相差2. 当每轮最少得到x个1,最多得到y个1 则1的个数范围[x,x+2...y-2,y]中都能取到,维护1的可取个数 组合数累加即可. #include <bits/stdc++.h> using namespace

HDU 6092 Rikka with Subset 思维 递推

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6092 题目描述: 给你一个集合的所有子集各个和, 让你找到这个集合, 输出字典序最小 解题思路: 下标0上的数字肯定是1, 所以从下标为1的开始向后, 第一个不为零的数的下标肯定是集合中的一个数而且是最小的数......同时将这个数减减, 记住这个下标为cur(所以这个集合应该是唯一的?我没严格证明, 但是每一步取得值肯定都是唯一的啊, 而且从小到大)这样我们向后面偏移cur个单位, 如果两个数都

!HDU 4311 最小曼哈顿距离-思维&amp;卡时间-(横纵坐标分开算,排序)

题意:有n个点,求以这n个点中的某一点为起点,到各点的曼哈顿距离和最小是多少 分析: 暴力枚举又要超时,这种题一般都是考思维了,多半都是用技巧找到一个高效的方法.个人觉得这题跟上一篇文章的题是一个类型.这种思想要记住. 这题也是用"分治",虽说题目要求的是曼哈顿距离,但是我们为什么真的就要一步到位的求呢,可以横纵坐标分开求,先x排序,然后遍历一遍,求出横坐标的距离,然后y排序,遍历一遍求出坐标的距离加在刚才求得的x的距离上,就是曼哈顿距离了. 这里有一个非常巧妙但是其实很显而易见的东西

HDU 5538 House Building(模拟——思维)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5538 Problem Description Have you ever played the video game Minecraft? This game has been one of the world's most popular game in recent years. The world of Minecraft is made up of lots of 1×1×1 blocks

2016多校第4场 HDU 6076 Security Check DP,思维

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6076 题意:现要检查两条队伍,有两种方式,一种是从两条队伍中任选一条检查一个人,第二种是在每条队伍中同时各检查一个,前提是两条队伍中的两个人的序号大于k.然后询问检查最少需要的时间. 解法:根据题意很容易想到dp[i][j]表示第一个队伍已经检查完前i个人,第二个人已经检查完前j个人所需最小时间.但是这样是O(n^2)毫无疑问会tle.我们发现k很小,所以我们可以对于两种转移方式分开处理.对于差值小

hdu 5317 RGCDQ 多校 思维题

点击打开链接题目链接 RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 328    Accepted Submission(s): 164 Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find