2016 Multi-University Training Contest 7
2016-08-10 17:22
204 查看
1. 1002-HDU 5810 Balls and Boxes
题意:给定n个球,m个盒子,将n个球抛入m个盒子,对于每种情况,定义,
是第i个盒子中球的个数,
是所有盒子中的球的个数的平均数,即n/m。求V的期望E(V)。
题解:
首先化简公式。
又由于
,
所以
首先对于每个盒子,每个球落入其中的概率是p=1/m,落不进的概率为1-p=1-1/m。所以对于每个盒子,
满足二项分布。
所以
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; int main() { int n,m; while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; LL fenzi=1ll*n*(m-1),fenmu=1ll*m*m; LL g=__gcd(fenzi,fenmu); printf("%I64d/%I64d\n",fenzi/g,fenmu/g); } return 0; }
2. 1005-HDU 5813 Elegant Construction
题意:让你构造出一个图使得其满足第i个点能到达的点的个数为ai个,没有环和重边。题解:按 ai 从小到大排序,在比 i 点与比其 ai 值小的点 j 之间连 aj 条边即可,只要出现 ai 值大于i,则一定不可能满足。
代码:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int MAX=1000+10; struct node { int id,x; bool operator <(const node &a) { return x<a.x; } }a[MAX]; int main() { int T; scanf("%d",&T); for(int tcase=1;tcase<=T;tcase++) { int n; scanf("%d",&n); int sum=0; for(int i=0;i<n;i++) { scanf("%d",&a[i].x); sum+=a[i].x; a[i].id=i+1; } sort(a,a+n); int flag=1; for(int i=0;i<n;i++) { if(a[i].x>i) { flag=0; break; } } printf("Case #%d: %s\n",tcase,flag?"Yes":"No"); if(flag) { printf("%d\n",sum); for(int i=0;i<n;i++) { for(int j=0;j<a[i].x;j++) { printf("%d %d\n",a[i].id,a[j].id); } } } } return 0; }
3. 1009-HDU 5818 Joint Stacks
题意:模拟栈操作,并在栈操作基础上多加一种操作merge A B,该操作可将栈A和栈B内的元素按输入顺序塞进栈A中,并清空栈B。问在执行pop操作时,弹出的元素是多少?题解:(参考:http://blog.csdn.net/queuelovestack/article/details/52164782)
关键是merge操作,如果重新再操作一次序列复杂度太高。这个合并起来的 应该一直是保存的,为merge操作准备。我们可以用一个数组来模拟。用两个指针来指向a和b分栈顶元素。用一个pre[]数组来记录每个位置的前驱。
每次push操作,在数组后面添加元素,移动相应指针。
每次merge操作,如merge A B ,将A指针指向a,b指针较高的一个,B指针指向栈底0位置;并将pre[a]=-1,表示该位置前面的数都为一个栈中的值。
每次pop操作,将当前位置标记为已经删除。如果pre值为-1,则一直往前删直到遇到一个没有被删除(执行过弹出操作)的数,否则直接将指针前移即可。
贴上流程(非原创):
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAX=1e5+10; int s[MAX],del[MAX]; int pre[MAX]; int a,b,cnt; int main() { //freopen("in.txt","r",stdin); int cas=1; int n; while(scanf("%d",&n)&&n) { printf("Case #%d:\n",cas++); char op[10],ob,oba,obb; int num; memset(pre,0xff,sizeof(pre)); memset(del,0,sizeof(del)); int a=0,b=0,cnt=0; for(int i=0;i<n;i++) { scanf("%s",op); if(op[1]=='u') { scanf(" %c %d",&ob,&num); s[++cnt]=num; if(ob=='A') { pre[cnt]=a; a=cnt; } else { pre[cnt]=b; b=cnt; } } else if(op[1]=='o') { scanf(" %c",&ob); if(ob=='A') { printf("%d\n",s[a]); del[a]=1; if(pre[a]==-1) { do { a--; }while(del[a]==1); pre[a]=-1; } else a=pre[a]; } else { printf("%d\n",s[b]); del[b]=1; if(pre[b]==-1) { do { b--; }while(del[b]==1); pre[b]=-1; } else b=pre[b]; } } else if(op[1]=='e') { scanf(" %c %c",&oba,&obb); if(oba=='A') { a=max(a,b); b=0; pre[a]=-1; } else { b=max(a,b); a=0; pre[b]=-1; } } } } return 0; }另外,标程写的简洁到爆啊。
比较简单巧妙的一个做法是引入一个新的栈C,每次合并的时候就把A和B合并到C上,然后把A和B都清空. push还是按正常做,pop注意当遇到要pop的栈为空时,因为题目保证不会对空栈进行pop操作,所以这时应直接改为对C栈进行pop操作. 这样做因为保证每个元素最多只在一次合并中被处理到,pop和push操作当然也是每个元素只做一次,所以总复杂度是O(N)的.
用到一个merge函数:
merge函数的作用是:将两个有序的序列合并为一个有序的序列。
函数参数:merge(first1,last1,first2,last2,result,compare);//firs1t为第一个容器的首迭代器,last1为第一个容器的末迭代器,first2为第二个容器的首迭代器,last2为容器的末迭代器,result为存放结果的容器,comapre为比较函数(可略写,默认为合并为一个升序序列)。
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAX=1e5+10; int x[MAX]; int sta[3][MAX],top[3]; int main() { int cas=1; int n; while(scanf("%d",&n)&&n) { printf("Case #%d:\n",cas++); char op[10],s[3]; memset(top,0,sizeof(top)); for(int i=0;i<n;i++) { scanf("%s %s",op,s); int ob=s[0]-'A'; if(op[1]=='u') { scanf("%d",&x[i]); sta[ob][++top[ob]]=i; } else if(op[1]=='o') { if(!top[ob]) ob=2; printf("%d\n",x[sta[ob][top[ob]--]]); } else { scanf("%s",s); top[2]=merge(sta[0]+1,sta[0]+top[0]+1,sta[1]+1,sta[1]+top[1]+1,sta[2]+top[2]+1)-sta[2]-1; top[0]=top[1]=0; } } } return 0; }
相关文章推荐
- 2016 Multi-University Training Contest 1 1011 tetrahedron
- 2016 Multi-University Training Contest 1 1011(HDU 5733 计算几何)
- 2016 Multi-University Training Contest 2 Keep On Movin
- 2016 Multi-University Training Contest 2 Eureka
- (HDU 5754)2016 Multi-University Training Contest 3 Life Winner Bo (博弈/DP)
- 【HDU5730 2016 Multi-University Training Contest 1H】【FFT + cdq 分治】 Shell Necklace f[i]=∑f[i-j] x a[j]
- 2016 Multi-University Training Contest 3 hdu 5752 Sqrt Bo【思维】
- 2016 Multi-University Training Contest 3 1002 Permutation Bo
- 【HDU5744 2016 Multi-University Training Contest 2K】【水题 贪心】Keep On Movin 给定字符使得最短回文串最长
- 2016 Multi-University Training Contest 3 1004 Gambler Bo(高斯消元)
- hdu 5773 2016 Multi-University Training Contest 4(LIS变形)
- 2016 Multi-University Training Contest 2 -Keep On Movin
- hdu 5763 Another Meaning(2016 Multi-University Training Contest 4——dp+kmp)
- 2016 Multi-University Training Contest 3 1003 Life Winner Bo (博弈)
- [HDU5788] Level Up [2016 Multi-University Training Contest 5 1008 (2016多校联合训练5)]
- (HDU 5794)2016 Multi-University Training Contest 6 A Simple Chess (Lucas、容斥)
- hdu 5794 2016 Multi-University Training Contest 6(鲁卡斯+容斥原理)
- hdu 5802 2016 Multi-University Training Contest 6(dfs)
- (HDU 5816)2016 Multi-University Training Contest 7 Hearthstone (状压DP、搜索)
- hdu 5810 Balls and Boxes(2016 Multi-University Training Contest 7——数学题)