BZOJ2223 PATULJCI COCI2009_CONTSET3

背景:
背景
输入:
输入
输出:
输出
大意:
白雪公主和N个小矮人住在森林里。每天早上,矮人们排成一队出去挖矿的路上,白雪公主就负责给他们拍照,并把这些照片传到社交网络上去。
白雪每次都会拍很多照片,她要从中选出一些完美的照片。小矮人们都戴着不同颜色的
帽子。如果照片上小矮人们有一半以上人戴着相同颜色的帽子,则这张照片就算是美丽的。
也就是说,如果照片上有K个人,如果有多于K/2的人带着相同颜色的帽子,则这张照片就是美丽的。
现在,写一个程序来检测相片集M是不是美丽的,并且判断出美丽照片上,哪种是主要的颜色。

思路:我们可以考虑一个随机算法,在区间 [A,B] 中任意找到一个值,如果有照片是pretty的,那么找一次找到的可能性就是 >12 的。所以只要我们枚举到20次那么我们错误的概率就会远小于 220 就很不容易错了。那么我们可以想想怎么判断是否是pretty的。
首先,我们可以以颜色为第一关键字,小矮人的位置为第二关键字排个序(颜色可以升序,可以降序,主要是为了把颜色集中,小矮人的位置按照升序)。然后我们便可以用二分查找找到某个区间内的某种颜色的小矮人的数量了(用大于这个 (颜色,位置) 的第一个减去大于等于 大于等于的第一个,便是数量了)。
然后根据随机的思想,我们就可以完成这道题了。

附上代码:

#include<cstdio>
#include<algorithm>
#define PII pair<int, int>
const int S = 17;      //控制随机的次数
#define MAXN 300005
using namespace std;
int a[MAXN];
PII b[MAXN];
int n, m, q;
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++)
    {
        scanf("%d", &a[i]);
        b[i] = PII(a[i], i);
    }
    sort(b + 1, b + n + 1);
    int t1, t2;
    scanf("%d", &q);
    while(q --)
    {
        scanf("%d%d", &t1, &t2);
        int i, x, cnt;
        for(i = 1; i < S; i ++)
        {
            x = a[t1 + rand()%(t2 - t1 + 1)];
            cnt = upper_bound(b+1, b + n +1, PII(x, t2)) - lower_bound(b + 1, b + n + 1, PII(x, t1));     //找有几个x颜色的在这个区间内。
            if(cnt * 2 > (t2 - t1 + 1))
                break;
        }
        if(i == S)           //没找到
            puts("no");
        else printf("yes %d\n", x);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值