娱乐大众,出一道前段时间做过的算法题,有兴趣的朋友可以玩一下:)

currenttt 2008-10-10 12:50:06
呵呵,在下也是新人,没多少分可用,感觉这个问题比较有代表性就贴出来与大家共享,有兴趣的朋友可以做做看:)

先说一下题目出处:来自ACM上的某道编程题,需要用二分法解答

== 题目描述 ==
一副扑克牌有4种花色的牌各13张,再加上大小王2张,总共有54张牌。一般你买的一副新扑克牌里除了这54张牌外还会有一两张特殊的牌,如果你不小心弄丢了54张牌中的某一张,就可以用特殊牌来代替,但是如果你弄丢两张的话就没有办法了,因为特殊牌上的图案是一样的。

现在你得到了很多扑克牌,准确来说,54种牌你各有a1、a2、……、a53、a54张,同时你还有b张特殊牌,现在你需要从这些牌中整理出若干副牌供大家使用。整理出的一副牌可以由54种普通牌各一张组成,也可以由53种普通牌各一张再加一张特殊牌组成。

== 要求 ==
输入:55种牌各自有多少张,每张牌的数目不大于1000000
输出:最多可以整理出多少张牌

== 示例输入 == //11是特殊牌的数目,下面的54个数字是54张牌各自的数目
11
5 4 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 10 10 10

== 示例输入对应的输出 ==
9
...全文
241 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jixuan1989 2011-07-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 litaoye 的回复:]

(我说的方法仅仅是一种实现方法,计算效率不高,提高效率可以先用直方图统计一下所有牌的张数,然后一遍就能算出来了)
[/Quote]mark
楼主的代码看了,思想一样,但是用了二分法,而不是一楼的一次+1.
至于1L的直方图统计,一遍就出来了 可以解释一下吗
currenttt 2008-10-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 ft1512975 的回复:]
呵呵,不仅是娱乐。
我现在还不明白这些东西,或许以后就明白了。
八皇后
[/Quote]

呵呵,如果感兴趣的话可以看下我的实现代码,基本原理就是鸽笼原理啦~


#include<iostream>
using namespace std;

int card[55];

int test(int l, int r)
{
if (l == r)
{
return l;
}
int k = (l + r) / 2;
if (l + 1 == r)
{
k++;
}

int m = 0;

for (int i = 1; i < 55; i++)
{

if (card[i] < k)
{
m = m + (k - card[i]);
}
}
if (m <= k && m <= card[0])
{
return test(k, r);
}
else
{
return test(l, k - 1);
}
}

int main()
{
int max;
while (cin >> card[0])
{
max = card[0];
for (int i = 1; i < 55; i++)
{
cin >> card[i];
if (max < card[i])
{
max = card[i];
}
}

cout << test(0, 2*max) << endl;
}
system("pause");
return 0;
}
  • 打赏
  • 举报
回复
呵呵,不仅是娱乐。
我现在还不明白这些东西,或许以后就明白了。
八皇后
  • 打赏
  • 举报
回复
呵呵,不仅是娱乐。
我现在还不明白这些东西,或许以后就明白了。
八皇后
currenttt 2008-10-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 test4ever 的回复:]
支持LZ,我也要娱乐,娱乐...
(5个小时后...)

老板:你今天工作成果如何丫?
答道:正在二分,勿扰~
老板寻思:不错,这小子工作真认真!
.....

lol

支持LZ多发娱乐题目~
[/Quote]

3x~这种小问题也就即兴活跃一下大脑,没有别的作用了~~
currenttt 2008-10-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tailzhou 的回复:]
首先m不可能大于最小的两数的和;
所以m不可能大于2*1000000 < 2^21;

对于给定的m,可以用1L的方法来判断是否合法;
[/Quote]

呵呵,是的,1L的算法完全正确:)
test4ever 2008-10-10
  • 打赏
  • 举报
回复
支持LZ,我也要娱乐,娱乐...
(5个小时后...)

老板:你今天工作成果如何丫?
答道:正在二分,勿扰~
老板寻思:不错,这小子工作真认真!
.....

lol

支持LZ多发娱乐题目~
tailzhou 2008-10-10
  • 打赏
  • 举报
回复
首先m不可能大于最小的两数的和;
所以m不可能大于2*1000000 < 2^21;

对于给定的m,可以用1L的方法来判断是否合法;






currenttt 2008-10-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 litaoye 的回复:]
说一下思路吧!
……
(我说的方法仅仅是一种实现方法,计算效率不高,提高效率可以先用直方图统计一下所有牌的张数,然后一遍就能…
[/Quote]

呵呵,1L的算法看明白了,我也是用鸽笼原理解的这个问题,不过如果能假定一个最大可能的答案,再用二分法进行判断,效率应该能提高不少
绿色夹克衫 2008-10-10
  • 打赏
  • 举报
回复
修正一下,是

如果sum <= m 且 sum <= x,上面的没有=号,忘记了
绿色夹克衫 2008-10-10
  • 打赏
  • 举报
回复
说一下思路吧!

设:

有特殊牌x张,共可以组成m付牌

先找到54个数中最小的,也就是例子中的4,从4 + 1试起,m = 5

统计所有小于m的张数k,计算所有m - k(5 - k)的加和sum,本例中为1,

如果sum < m 且 sum < x

m++(m = 6)

重复上面的统计,直到sum > m 或 sum > x

m就是要找的数

(我说的方法仅仅是一种实现方法,计算效率不高,提高效率可以先用直方图统计一下所有牌的张数,然后一遍就能算出来了)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧