2015.08.08总结
来源:互联网 发布:动力学仿真软件ls 编辑:程序博客网 时间:2024/06/05 20:36
NOIP2015提高组模拟8.8
P1 3476. 【NOIP2013初赛】整除
这题其实是一道货真价实的水题,正解就是DFS+容斥原理。先DFS枚举若干个数的Lcm再根据容斥原理计算,可得出答案。顺便,可以将题目转化为求[1~R]-[1~L-1],便于处理。
P2 3473. 铺砖问题
嘛。。。经典问题,就个人感觉来说,这道题是这套题中最难的一道。正解是矩阵优化+快速幂。50分的状压DP(设F[i][j]表示做完前i列),可以预处理出转移的状态,便于后面的转移。另外的50分用矩阵乘法+快速幂来处理,还是先DFS预处理一个矩阵Mat,Mat[i][j]=1表示压缩后的状态可以转移到j,再求该矩阵的n次幂,最后答案就是Mat[0][0].
SRC:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 100+10#define M 2500+10typedef long long ll;const int Mo=1000000007;struct Matrixtype { int mat[N][N];}a,b,tmp,ma;int n[210];int jl[M][M],f[2][M];char s[210];int m,maxn,ans;void Pre(int st,int k,int num) { if(k>=m) { jl[st][++jl[st][0]]=num; return; } if((1 << k) & st) {Pre(st,k+1,num); return;} Pre(st,k+1,num+(1 << k)); if(k+1<m && !((1 << (k+1)) & st)) Pre(st,k+2,num);}void Make(int st,int k,int num) { if(k>=m) { ma.mat[st][num]=1; return; } if((1 << k) & st) {Make(st,k+1,num); return;} Make(st,k+1,num+(1 << k)); if(k+1<m && !((1 << (k+1)) & st)) Make(st,k+2,num);}int Div() { int r=0; for(int i=n[0];i>0;i--) { n[i]+=r*10; r=n[i]%2; n[i]/=2; } if(!n[n[0]]) n[0]--; return r;}Matrixtype mult(Matrixtype a,Matrixtype b) { Matrixtype c; memset(c.mat,0,sizeof(c.mat)); for(int i=0;i<=maxn;i++) { for(int j=0;j<=maxn;j++) { for(int k=0;k<=maxn;k++) { c.mat[i][j]=(c.mat[i][j]+(ll)a.mat[i][k]*b.mat[k][j])%Mo; } } } return c;}void Quickmi() { for(int i=0;i<=maxn;i++) tmp.mat[i][i]=1; while(n[0]) { int rest=Div(); if(rest) tmp=mult(tmp,ma); ma=mult(ma,ma); }}int main(){ freopen("p2.in","r",stdin); freopen("p2.out","w",stdout); scanf("%s%d",s,&m); int len=strlen(s); maxn=(1 << m) - 1 ; if(m>5) { f[0][0]=1; int nn=0,now=0; for(int i=0;i<len;i++) nn=nn*10+s[i]-'0'; for(int i=0;i<=maxn;i++) Pre(i,0,0); for(int i=0;i<nn;i++) { for(int j=0;j<=maxn;j++) { if(!f[now][j]) continue; for(int k=1;k<=jl[j][0];k++) { f[~now][jl[j][k]]=(f[~now][jl[j][k]]+f[now][j])%Mo; } } memset(f[now],0,sizeof(f[now])); now=~now; } ans=f[now][0]; } else { n[0]=len; for(int i=0;i<len;i++) { if(i==len-1) { i++; i--; i++; i--; } n[len-i]=s[i]-'0'; } for(int i=0;i<=maxn;i++) Make(i,0,0); Quickmi(); ans=tmp.mat[0][0]; } printf("%d\n",ans);}
P3 3475. 【NOIP2012初赛】新壳栈
初赛原题,这题可以维护一个双向队列和一个栈,对于栈顶的c个元素,我们放入队列中,其余元素放在栈中。对于翻转操作只需要O(1)交换队头和队尾指针即可。但不知为什么,用C++的reverse()跑的特别快,因此诞生了一种水法。
水法:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 1000000+10int q[N];int c,k,top;int main(){ scanf("%d",&c); scanf("%d",&k); while(k!=0) { if(k==1) { int e; scanf("%d",&e); q[++top]=e; } if(k==2) { if(top<1) printf("Error: the stack is empty!\n"); else printf("%d\n",q[top]),top--; } if(k==3) { if(top<c) printf("Error: less than %d elements in the stack!\n",c); else reverse(q+1+top-c,q+1+top); } scanf("%d",&k); } return 0;}
P4 【NOIP2013初赛】青蛙
我们设F[i]表示n=i的答案。易得F[i]=(F[1]+F[2]+…+F[i])/n+1,
化简得F[i]=(F[1]+F[2]+…+F[i-1]+i)/(n-1)
SRC:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 20000+10double f[N],s[N];int n;int main(){ scanf("%d",&n); for(int i=2;i<=n;i++) f[i]=(s[i-1]+i)/(i-1),s[i]=f[i]+s[i-1]; printf("%.2f\n",f[n]); return 0;}
以上.
0 0
- 2015.08.08总结
- eclipseRCP深入浅出(学习总结)2015.08.08
- 2015.08.10总结
- Galbanum之08总结
- 08年杂想总结
- 08总结篇--投资
- 08年 ,JavaScript总结
- 08年 ,JavaScript总结
- 08年总结
- 2011-08-26 总结
- 08年年终总结
- 12-11-08 总结
- 08--java异常总结
- 2010.10.08学习总结
- 2014.10.08面试总结
- 2015.07.08总结
- Android总结(2012.07.08)
- 08-CoreData学习总结
- Android下获取各种存储目录
- 个人对Android Touch事件机制的理解
- 基于消息机制的异步架构之消息队列
- java面向对象
- tcp3次握手和4次挥手全过程
- 2015.08.08总结
- hdu 5375 Gray code (简单DP)
- 面试复习重点——基础篇:操作系统、计算机网络、设计模式【山科大牛陈磊整理】
- warning:deprecated conversion from string constant to 'char *'解决方案
- 29-HTML-04-HTML(列表标签)
- hdu 5379
- 29-HTML-05-HTML(图像标签)
- HDU 5375 Gray code(DP)
- Servlet与JSP