SDUT网络赛
来源:互联网 发布:铁路计算坐标数据库 编辑:程序博客网 时间:2024/05/21 03:19
只写三个题,一个是飞行棋(期望DP),super prime(引申连续数字和等于一个数的问题)和Dota人王之战
一,飞行棋:
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2503
思想如下:
首先明白什么叫数学期望。http://en.wikipedia.org/wiki/Mathematical_expectation
其次,这个题中一定要搞明白,限制条件是期望得分需要大于等于所给格子数,而输出的是期望的掷色子次数。在这个题中,对于1的期望值,就是剩余一个格子,掷色子的期望值。即,获胜所需的掷色子次数。
当格子数目是1时:只需要投一次色子,故期望为1;
当格子数目是2时:掷色子,2,3,4,5,6都可能出现,他们是绝对获胜的,所以期望是sigma(出现次数*频率),就是1,然后,如果掷到1,剩余一个格子,获胜期望是dp[1],出现概率是1*dp[1];期望是1+1/6*dp[1];
当格子数目是3时:3,4,5,6都可能出现,是绝对获胜的,他们的期望是1,然后,如果掷到1,剩余两个格子,获胜期望是dp[2],如果掷到2,剩余一个格子,获胜期望是dp[1];期望是1+1/6*(dp[1]+dp[2]);
...
当格子数目是6时:6可能出现,是绝对获胜的,他的期望是1,然后,如果掷到1,剩余五个格子,获胜的期望是dp[5],如果掷到2,剩余四个格子,获胜期望是dp[4],如果掷到3,剩余三个格子,获胜期望是dp[3],如果掷到4,剩余两个格子,获胜期望是dp[2],如果掷到5,剩余一个格子,获胜期望是dp[1];期望是1+1/6*(dp[1]+dp[2]+dp[3]+dp[4]+dp[5]);
...
当格子数是n(n>=7)时,没有一次获胜的可能,所以需要掷一次,期望首先+1,然后,如果掷到1,剩余n-1个格子,获胜的期望是dp[n-1],如果掷到2,剩余n-2个格子,获胜的期望是dp[n-2],如果掷到3,剩余n-3个格子,获胜的期望是dp[n-3],如果掷到4,剩余n-4个格子,获胜的期望是dp[n-4],如果掷到5,剩余n-5个格子,获胜的期望是dp[n-5],如果掷到6,剩余n-6个格子,获胜的期望是dp[n-6];期望1+1/6*(dp[n-1]+dp[n-2]+dp[n-3]+dp[n-4]+dp[n-5]);
...
故,综上述,不难得出以下程序:
#include <iostream>#include <cstdio>using namespace std;double dp[10000];int main(){dp[1]=1.0;dp[2]=1.0/6*dp[1]+1;dp[3]=1.0/6*(dp[1]+dp[2])+1;dp[4]=1.0/6*(dp[1]+dp[2]+dp[3])+1;dp[5]=1.0/6*(dp[1]+dp[2]+dp[3]+dp[4])+1;dp[6]=1.0/6*(dp[1]+dp[2]+dp[3]+dp[4]+dp[5])+1;int t;cin>>t;while(t--){int n;cin>>n;for(int i=7;i<=n;i++){dp[i]=1.0/6*(dp[i-6]+dp[i-5]+dp[i-4]+dp[i-3]+dp[i-2]+dp[i-1])+1;}printf("%.4lf\n",dp[n]);}}
二,super prime
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2404
一直不明白为何错误。
但是其求连续子序列和是否等于某值的思想是可以借鉴的,一个双端队列的实现。详解请看程序:
#include <iostream>#include <cmath>#include <deque>#include <numeric>#include <functional>#include <stdlib.h>using namespace std;#define Max 100010bool prime[Max];void IsPrime(){ prime[0]=prime[1]=0;prime[2]=1; for(int i=3;i<Max;i++) prime[i]=i%2==0?0:1; int t=(int)sqrt(Max*1.0); for(int i=3;i<=t;i++) if(prime[i]) for(int j=i*2;j<Max;j+=i) prime[j]=0;}int main(){ IsPrime();int prime_real[10000];int j = 0;for(int i = 0 ; i < Max; i++){if(prime[i]){prime_real[j++] = i;}}/*for(int i = 0 ; i < j; i++){cout<<prime_real[i]<<' ';}system("pause");*/ int n;cin>>n;for(int t = 1; t < n; t++){int p;cin>>p;if(!prime[p]){cout<<"Case "<<t<<": no"<<endl;continue;}else{deque<int> a;a.push_back(prime_real[0]);for(int i = 1; i <= j; ){int sum = accumulate(a.begin(),a.end(),0);//计算当前的和if(sum < p)//如果和小于该定值,下一个数入队{a.push_back(prime_real[i++]);}else if(sum == p && a.size() != 1)//如果和等于该值,且不是它本身,输出yes并结束{cout<<"Case "<<t<<": yes"<<endl;break;}else if(sum > p && a.size() == 1)//如果和大于该值且队列大小是1,那么是不正确的,因为在维护和的过程中,和是一直在被不短加减的,如果加上这个大于它,说明不存在连续的,满足要求。{cout<<"Case "<<t<<": no"<<endl;break;}else//其他就属于加上当前的值,太大,所以要从队前弹出,保证连续性{a.pop_front();}}}}}
三,人王之战
这个民间有个游戏,跟这个很相似,叫倒三十或抢三十,请移步:http://hi.baidu.com/macchinetta/item/7e737d09ad97f232a3332aa1
有了上述基础,不难写出如下代码:
#include <iostream>using namespace std;int main(){int n,m;ios::sync_with_stdio(false);while(cin>>n>>m){if(n%(m+1)){cout<<"A new star rise"<<endl;}else cout<<"Orz Dota God"<<endl;}}
- SDUT网络赛
- 完美网络 SDUT 2506
- SDUT-2506 完美网络
- SDUT- 2506-完美网络
- sdut 2506 完美网络
- SDUT完美网络
- SDUT-完美网络
- SDUT 2056-完美网络
- sdut 第三届ACM/ICPC程序设计知识竞赛网络赛 字符串拓展
- SDUT 2560 完美网络(优先队列)
- sdut 2506 完美网络(优先队列)
- SDUT 第九周周赛
- SDUT月赛
- SDUT 第12周周赛
- SDUT OJ 2506 数据结构实验——完美网络
- sdut 完美网络 无向图的连通分量
- SDUT测试赛——Problem F
- SDUT-2109&&SDUT-3398
- POJ 3694 Network
- Javascript中的 this
- C#中播放背景音乐几种的方法
- java-hibernate-标准sql数据类型对应表
- 编译openwrt官方不支持的路由型号固件——以WR720N为例
- SDUT网络赛
- 微软面试(2/100)--设计包含函数的栈
- 编译个性化的openwrt固件
- spring framework源码下载并导入eclipse
- Java中==与equals()的区别
- java 宠物商店
- poj - 1077 - Eight
- 从linux内核启动说起~模块篇(四)
- 嵌入式学习笔记之GPIO