您的位置:首页 > 产品设计 > UI/UE

Divide and conquer:Showstopper(POJ 3484)

2016-01-30 22:45 441 查看
                


                Showstopper

  题目大意:数据挖掘是一项很困难的事情,现在要你在一大堆数据中找出某个数重复奇数次的数(有且仅有一个),而且要你找出重复的次数。

  其实我一开始是没读懂题意的。。。主要是我理解错object的意思了- -

  这一题原理要做出来不难,其实就是二分法,对数二分就好了,因为重复奇数次的数只有一个,所以肯定存在小于等于某一个数时的数的重复次数加起来是奇数,不断二分就可

  关键是是这一题的数据输入超级麻烦,他还会隔行输入。。。。用一行或者多行来区分数据。。。一开始我跳进这个坑里面了。。出题人有意思吗?

  不过还好,让我重新复习了sscanf的用法。。。网上找了个用法比较好的做范例吧。

  

#include <iostream>
#include <functional>
#include <algorithm>
#include <string.h>

typedef long long LL_INT;

struct _set
{
LL_INT set_att[3];
}refer[500005];

void Solve(const int, LL_INT);
LL_INT Max(LL_INT, LL_INT);
bool judge(LL_INT, const int);
int Cal_Sum(const int, LL_INT);

int main(void)//找出某个数出现的次数为奇数次的数
{
int sum = 0;
LL_INT max_num;
char str[100];

while (gets(str))
{
sum = 0;  max_num = -1; refer[0].set_att[0] = 0;
sscanf(str, "%lld %lld %lld", &refer[0].set_att[0], &refer[0].set_att[1], &refer[0].set_att[2]);
if (refer[0].set_att[0] == 0)
continue;
memset(str, 0, sizeof(str));
do{
sum++;
gets(str);
if (str[0] == 0) break;
sscanf(str, "%lld %lld %lld", &refer[sum].set_att[0], &refer[sum].set_att[1], &refer[sum].set_att[2]);
memset(str, 0, sizeof(str));
max_num = Max(max_num, refer[sum].set_att[1]);
} while (1);
Solve(sum, max_num);
}
return EXIT_SUCCESS;
}

LL_INT Max(LL_INT x, LL_INT y)
{
return x > y ? x : y;
}

int Cal_Sum(const int i, LL_INT ans)
{
if (ans<refer[i].set_att[0] || ans>refer[i].set_att[1])
return 0;
else if ((ans - refer[i].set_att[0]) % refer[i].set_att[2] == 0)
return 1;
else return 0;
}

void Solve(const int set_sum, LL_INT max_num)
{
LL_INT lb = 0, ub = max_num, mid, res = 0;

while (ub - lb > 1)
{
mid = (lb + ub) >> 1;
if (judge(mid, set_sum)) ub = mid;
else lb = mid;
}
for (int i = 0; i < set_sum; i++)
res += Cal_Sum(i, ub);
if (res % 2)
printf("%lld %lld\n", ub, res);
else
printf("no corruption\n");
}

bool judge(LL_INT mid, const int set_sum)
{
//只用统计mid(包含mid)的半边就可以了,因为出现奇数次的数只有一个
LL_INT refer_sum = 0;
for (int i = 0; i < set_sum; i++)
{
if (mid < refer[i].set_att[0])//没有任何数出现在左边
continue;
else if (mid > refer[i].set_att[1])
refer_sum += (refer[i].set_att[1]- refer[i].set_att[0]) / refer[i].set_att[2] + 1;
else
refer_sum += (mid - refer[i].set_att[0]) / refer[i].set_att[2] + 1;
}
return refer_sum % 2 ? 1 : 0;
}


  


  参考/article/2461617.html

    http://blog.csdn.net/u012825876/article/details/27854225
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: