分享几个有趣的题目 散分

fanster28_ 2010-06-20 08:43:51
近一个月常来csdn,这个月下来收获还是不少,以后可能来的机会没这么多了,csdn上长期有帮别人
解答的问题的大牛在,比如litaoye michael122 superdullwolf FancyMouse 等等等
由于我来的时间不多,所以还有n多的牛牛们的名字也不晓得,就没有列了,在此让我们对这些牛牛们拍手致敬 ~~~

^_^

最近没有多少新题目,为数不多的新题目又太难或者太简单,给大家分享几个需要一点思考却也不算复杂的题目,来对一个月在csdn的收获画上一个标点符号。。。

题目一:
用n个1和m个0组成字符串,要求任意的前k个字符中,1的个数不能少于0的个数。
问满足要求的字符串数目。(结果取除以20100403的余数)

输入数据是一行,包括2个数字n和m (1<=m<=n<=1000000)

比如如输入
2 2
1000000 999999

输出
2
12235810

题目二:
定义“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888
定义“近似幸运号码”是能被任意一个幸运号码整除的那些号码,比如6,8,12,16
现在问对闭区间[a, b],“近似幸运号码”的个数

输入数据是一行,包括2个数字a和b
1<=a<=b<=10000000000

输出“近似幸运号码”的个数

比如输入:
1 10
1234 4321

输出
2
809

题目三:
通过掷色子来确定4个2位数, 将色子掷8次, 每次掷完之后必须马上决定这个数字成为哪个数字的哪一位(例如第2个数的个位),
然后才能掷下一个数字. 最后的4个数字数字的和即为一次游戏的得分, 但是如果该数字>170的话则得分为零.

实现你能给出的最优策略,并使用该策略玩上10000次,看看你的得分是多少.
...全文
412 点赞 收藏 39
写回复
39 条回复
liqi4960710 2010年06月25日
好多牛人啊!!!————围观
回复 点赞
wuzhanhui 2010年06月25日
[Quote=引用 37 楼 inflexible_lin 的回复:]
C/C++ code
#include <iostream>
const int MY_LONG_LIMIT = 20100403;
int sum;

void Test(long n, long m)
{
if(n <=1 && m <= 1){
//结束条件
}else if(n > m){
for(l……
[/Quote]
这个不错
回复 点赞
fanster28_ 2010年06月24日
p比较小m+n很大计算阶乘没必要这样了算了
fac[p]^((m+n)/p)*fac[(m+n)%p]就可以了嘛
n!分解一个素数一个素因子p是lgp(n) 全部分解出来还是lg(n)么,没细想过
还有最后得到因子求幂综合起来
回复 点赞
绿色夹克衫 2010年06月24日
看完球了,今天这两场押宝全赔了,不过我宁愿丢200分,也希望英美国出现。虽然我不太喜欢这两个国家的外交政策,但不影响喜爱他们的球员。

又想了一下这几个问题,第二题除了容斥,似乎没有太好的方法,预处理时间稍微长一些,之后每处理一个数需要枚举一下所有的容斥集合,不过也就是10^4量级的,还可以了。

第一个问题,我肯定会用拆分的方法,也许不一定要完全拆分为质数,可以靠一个数组做约分,拆分为质数的话,就是n*log(n)了。如果20100403变的小一些的话,比如10007,那么用逆元的方法会让效率提高很多,不过也很有可能根本不用算,结果就是0。

第三个问题,如果是我想策略,就是开始尽量选择小一些的,前3个的和尽量不超过104,最后1次,第一个数>3就当做十位,否则当做个位,不知道算不算是个凑合的策略,感觉应该比较弱。
回复 点赞
绿色夹克衫 2010年06月24日
其实我的意思是,欧几里得扩展是对数级,但阶乘取Mod还是要算的,所以是O(m+n),如果Mod的这个数p比较小,即使n,m非常大,仍然可以在O(p)+log(n)的时间求解。

第二题的方法还是比较暴力,我是先把小于10^9的所有幸运数字都求出来,先筛选一遍66,88这类的,然后直接把所有小于10^9的lcm也求出来(可以用类似优先队列的方法),之后再算,如果只算一组的话,我这个方法无疑很浪费,如果同时算多组的话,还比较划算。

[Quote=引用 31 楼 fanster28_ 的回复:]

因为20100403是素数,求逆元也就对数级的,怎么都无所谓了。

预先求出幸运数字,排序,再去除66 88这样的,剩下1000个左右
给定a,b 可以二分把不大于b的幸运数字ln[n]的n找出来
int f(int n,int val) {
int ans=b-a;
for i = 0 to n-1
int g=lcm(ln[i])
……
[/Quote]
回复 点赞
xinzaiyiqi 2010年06月24日
学习中……
回复 点赞
fanster28_ 2010年06月24日
因为20100403是素数,求逆元也就对数级的,怎么都无所谓了。

预先求出幸运数字,排序,再去除66 88这样的,剩下1000个左右
给定a,b 可以二分把不大于b的幸运数字ln[n]的n找出来
int f(int n,int val) {
int ans=b-a;
for i = 0 to n-1
int g=lcm(ln[i])
if(g<=b) ans-=f(i,g)
ret ans
}
注意一下数的取值范围,还有就是求lcm是可能乘爆int64就可以了
[Quote=引用 29 楼 litaoye 的回复:]
第一个问题,我肯定会用拆分的方法,也许不一定要完全拆分为质数,可以靠一个数组做约分,拆分为……
[/Quote]
回复 点赞
aleyn 2010年06月24日
#include <iostream>
const int MY_LONG_LIMIT = 20100403;
int sum;

void Test(long n, long m)
{
if(n <=1 && m <= 1){
//结束条件
}else if(n > m){
for(long i=0; i < m; ++i){
Test(n-1, m-i);
}
}else if(n == m){
for(long i=1; i < m; ++i){//i从1开始
Test(n-1, m-i);
}
}
if(sum == MY_LONG_LIMIT){
sum = 0;
}else{
++sum;
}
}

int main()
{
sum = 0;
Test(2,2);//对输入不做检查了, 如要写Test(2,3)这样的, 本人不管
std::cout << sum << std::endl;

sum = 0;
//Test(20,19);
Test(100000,99999); //一个半小时的数据还没跑完
std::cout << sum << std::endl;

system("pause");
return 1;
}
回复 点赞
绿色夹克衫 2010年06月24日
球赛之前又想了一下第3题,感觉上面说的这个方法太凭感觉了,应该先确定一下,总共可以定的策略为64种,先把这64种策略的平均期望求一下,然后根据每一次的结果,不断调整策略,利用决策树多搜索几层,才能比较准确,否则完全凭感觉来选,确实不太理智,也不符合科学发展的国策。
回复 点赞
fanster28_ 2010年06月24日
其实放在哪里没有关系,无非放在十位还是个位上
回复 点赞
绿色夹克衫 2010年06月24日
其实说的是同一回事儿,呵呵,不继续说下去了。问一下第3题,我说的思路靠谱么?

[Quote=引用 34 楼 fanster28_ 的回复:]
p比较小m+n很大计算阶乘没必要这样了算了
fac[p]^((m+n)/p)*fac[(m+n)%p]就可以了嘛
n!分解一个素数一个素因子p是lgp(n) 全部分解出来还是lg(n)么,没细想过
还有最后得到因子求幂综合起来
[/Quote]
回复 点赞
绿色夹克衫 2010年06月22日
这两天看球看得昏天黑地。第二题用容斥算了一个,效率很低,应该不算好方法,再想想。
其实我进来主要是看看FancyMouse牛的,哈哈。
回复 点赞
超级大笨狼 2010年06月22日
这两天没看球,也昏天黑地的,早晨居然睡到了9点20,到公司是10点52分。
回复 点赞
lele140 2010年06月22日
高手云集啊。MARK...
回复 点赞
fanster28_ 2010年06月21日
嗯,第一题,这个结果对了,大家可以自己先思考一下如何证明,然后思考得到此结果后如何实现(其实原题本来也要通过这两步分析才能得到解)
[Quote=引用 5 楼 litaoye 的回复:]

第一题:可以转化为出栈入栈的问题,学着推catalan数的方法推算了一个,不知道对否,c(m+n,m) - c(m+n,m-1)
[/Quote]
回复 点赞
lin49940 2010年06月21日
这里牛人果然特别多啊, 受教了~
回复 点赞
michael122 2010年06月21日
第二题把小于10000000000的所有幸运数都列出来,不多,一共2046个
然后用类似于筛选素数的办法应该就可以了,或者用容斥原理也可以做

不知道时间上会不会是问题
实际上需要的幸运数没有那么多,比方说66,88这些都不需要了
如果用筛素数的办法的话,内存放不下这么大的数组,需要把数组拆开成几个来做
回复 点赞
michael122 2010年06月21日
[Quote=引用 5 楼 litaoye 的回复:]

第一题:可以转化为出栈入栈的问题,学着推catalan数的方法推算了一个,不知道对否,c(m+n,m) - c(m+n,m-1)
[/Quote]

正确



类似问题:
有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)

这是lz题目的特殊情况,n=m,推导跟这个一样
参考:http://blog.chinaunix.net/u3/94732/showart_2074106.html
回复 点赞
FancyMouse 2010年06月21日
> Test(100000,99999); 开赛前运行, 到我看完比赛还没计算出结果. 希望大牛们能指点下在下.
就是推广的catalan数。取模的数是质数所以阶乘+extgcd完事。直接枚举的话几亿年估计都算不出。
回复 点赞
笺香 2010年06月21日
学习了~
回复 点赞
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.0w+

社区成员

3.4w+

社区内容

数据结构与算法相关内容讨论专区
社区公告
暂无公告