ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:20.51KB ,
资源ID:11718670      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11718670.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ACM必做50题的解题数学.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ACM必做50题的解题数学.docx

1、ACM必做50题的解题数学ACM必做50题的解题-数学.txt36母爱是一缕阳光,让你的心灵即便在寒冷的冬天也能感受到温暖如春;母爱是一泓清泉,让你的情感即使蒙上岁月的风尘仍然清澈澄净。POJ 2249 Binomial Showdown组合数学。高精度,也可把分子分母的数组进行两两约分 #includeusing namespace std;double c(int c,int k) double a=1; int i,j=2; for(i=c;ic-k;i-) a=a*i/(c-i+1); return a;int main() int n,k; while(scanf(%d%d,&n,&

2、k)!=EOF & (n!=0 | k!=0) if(kn/2 )k=n-k; printf(%.0lfn,c(n,k); return 0;poj 1023 the fun number system (经典进位制)题意:一种由2进制衍生出来的进制方法(我们暂且称为“类2进制”); 标明n的位置上原2进制该位的权重要乘上-1,才是现在进制方法该位的权重; 譬如说;pnp对于的能表示的数2来说就是 110;即1*22+(-1)*1*21+1*20=2;算法:这是数论中的进位制问题,我们可以仿照原来的求一个数二进制表示方法; 但首先,我们应该考虑几个问题;k位这种类2进制的表示范围;显然,当给出

3、的p,n序列中,我们将所有p的位置都置为1其余位是0,此时最大;当我们将所有n的位置置为1,其余为0,此时最小;不过当我们求最大限max和最小限min时会有一个溢出问题;比如64位全是p的序列,那么max会溢出,值为-1;同理min在全是n时也会溢出,为1;显然是max=0,min=1,溢出时产生异常,依次可以判断;是否是最大限和最小限之间的数都能表示呢?都可以,而且能够表示的数是2k个,这个原始2进制是一样的;因为每个位上要么是0,要么是1,而且每个位上的权重唯一的,不能通过其他位的01组合获得;最后,我们就可以仿照原始二进制来算在类2进制下的表示;不断求N的二进制最后一位和右移;如果取余是

4、1,则该位上一定是1,如果该位对于字母为n,则高位应该再加1;这里对2取余可能会出错,因为对于负数,补码的表示,最后一位一定是和原码一样的每次的右移后(有时需先加1)补码表示正好符合要求(可找实例验证);#includeusing namespace std;_int64 N,M;char s100,res100=0;int main() int T;scanf(%d,&T); int i,j; _int64 _max,_min; char ch; while(T-) scanf(%I64d,&N); scanf(%s,s); _max=0;_min=0; for(i=0;iN;i+) /找出

5、能表示的范围; if(si=p) _max=2*_max+1,_min*=2; else _min=2*_min-1,_max*=2; scanf(%I64d,&M); if(M_min&_min_max&_max=0) puts(Impossible); /注意防止64位数的溢出; else memset(res,0,sizeof(res); for(i=N-1;i=0;i-) int flag=0; if(M&1) /这里不能是平常的%2; resi=1; if(si=n) flag=1; else resi=0; M=1; if(flag) M+; /如果是n就需其高位加1; print

6、f(%sn,res); system(pause); return 0; POJ2506 Tiling 递推+高精给看似复杂的题找到了合适的规律就会变得简单。这个题就是这样。对于n列来说,可以在n-1列的基础上加上一块,或者是在n-2列的基础上加上2块而2块独立的,不依赖于1块的情况有两种,所以得到递推公式f(n)=f(n-1)+2f(n-2)看样例,要用到高精。#include/f(n)=f(n-1)+2f(n-2)using namespace std;int f251300;void HPprint(int *a) for (int i=a0;i=1;i-) coutai; couten

7、dl; void HPplus(int *a,int *b,int *c)int i,j;j=0;for(i=1;ib0?a0+2:b0+2;while(cc0=0 & c01) c0-; void HPmultyNUM(int *a,int b,int *c) int i,j,k; for (i=1;i=a0;i+) ci+=ai*b; k=0; for (j=1;j1) c0-; int main()int i,j,t300,test;f00=1;f01=1;f10=1;f11=1;f20=1;f21=3;for(i=3;itest) HPprint(ftest);return 0;POJ

8、 1079 Ratio 分数操作 题目大意:给出一个分数,比如1498/902。求出当分母分别为1, 2, .的时候,最接近1498/902的分数。比如:当分母为1的时候,最接近1498/902的分数为 1/1。当分母为2的时候,最接近1498/902的分数为 3/2。当分母为3的时候,最接近1498/902的分数为 5/3。思路:不要用高精度哦,直接模拟分数的操作最好了。#include #include struct frac _int64 up, down;_inline _int64 gcd(_int64 a, _int64 b) _int64 r; if (a b) r = a; a

9、 = b; b = r; while (1) r = a % b; if (!r) return b; a = b; b = r; _inline struct frac frac_init(_int64 up, _int64 down) _int64 r, s; struct frac f; r = up ? gcd(up, down) : 1; if (r 0) r = -r; f.up = up / r; f.down = down / r; return f;_inline struct frac frac_sub(struct frac fa, struct frac fb) ret

10、urn frac_init(fa.up*fb.down-fa.down*fb.up, fa.down*fb.down);_inline _int64 frac_cmp(struct frac fa, struct frac fb) return frac_sub(fa, fb).up;_inline struct frac frac_abs(struct frac f) if (f.up 0) f.up = -f.up; return f;int main() _int64 up, down; struct frac target, min_dis, f, dis; while (scanf(

11、%I64d%I64d, &up, &down) != EOF) target = frac_init(up, down); min_dis.down = 1; min_dis.up = (_int64)1e15; for (down = 1; down = target.down) up+; f = frac_init(up, down); dis = frac_abs(frac_sub(f, target); if (frac_cmp(dis, min_dis) 0) printf(%I64d/%I64dn, f.up, f.down); min_dis = dis; printf(n);

12、return 0;poj 1019 Number Sequence (找规律)找规律的题目:先计算出从1到n这个小区间有多长,保存到digit数组中,然后计算从112123到n一共有多少位数字,然后根据输入数据查找,其中我在找那一位时比较暴力,把从1开始一直存放,直到存放的比那一位还多,然后取出那一位。#include #include #include #include using namespace std ;const int MaxSize=100000+10 ;_int64 digitMaxSize, lenMaxSize ;stringstream ss ; void init()

13、 int i ; digit1 = len1 = 1 ; for( i=2; iMaxSize; +i ) digiti = digiti-1 + (int)log10(double)i)+1 ; leni = leni-1 + digiti ; /*for( i=1; i10; +i ) cout i 位数 digiti 长度 leni endl ; */char getDigit( int num ) int i ; for( i=1; leninum; +i ) ; int pos = num-leni-1 ; / 清空ss ss.str(); for( i=1; i=pos; +i )

14、 ss i ; /cout ss.str() sets ; while( sets- ) cin num ; cout getDigit( num ) =N)。而k=n-L0-L1- .-Ln-1。鉴于二叉树的固有特性,我可以构造递归函数fun(n,k)。即打印出拥有n个结点树的第k种状态。(2).继续转化问题,这棵树的左子树和右子树各有结点数多少?设这棵树左子树的结点数为i,右子树的结点数为n-i-1,那么这棵树是又左子树的结点数为i,右子树的结点数为n-i-1的形态的第几种(设为第s种)?可以知道当1=k=L0*Ln-1时,左子树结点树为0,右子树结点数为n-1,s=k;L0*Ln-1+1

15、=k=L1*Ln-2时,,左子树结点树为1,右子树结点数为n-2,s=k- L0*Ln-1 ;.当Li-1*Ln-i+10)打印(;fun(i, (s-1)/Ln-i-1+1);打印); 打印X; If(n-i-10) 打印(;fun(n-i-1, (s-1)%Ln-i-1+1);打印);至此,问题得到了解决。#include int L19=1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845,35357670,129644790,477638700; void fun(int n,int k) i

16、nt i,sum=0; if(1=n)putchar(X);return; for(i=0;ksum;i+)sum+=Li*Ln-i-1; i-; sum-=Li*Ln-i-1; k-=sum; if(i) putchar(); fun(i,(k-1)/Ln-i-1+1); putchar(); putchar(X); if(n-i-1) putchar(); fun(n-i-1,(k-1)%Ln-i-1+1); putchar(); int main() int n,i,j,sum; while(scanf(%d,&n)&n) sum=0; for(i=1;nsum;i+)sum+=Li;

17、i-; fun(i,n-sum+Li); putchar(n); return 0; POJ 1905 Expanding Rods#include #include #include using namespace std;int main(int argc, char* argv) double N,C,L; while(scanf(%lf%lf%lf,&L,&N,&C)&N=0&C=0&L=0) if(N=0|L=0|C=0) printf(0.000n); continue; double minv = 0,maxv = acos(-1.0), midv; double L2 = (

18、1 + N * C ) * L; while(maxv - minv 1e-12) midv = (minv + maxv) / 2; if( 2 * L2 / L midv / sin(midv / 2) minv = midv; else maxv = midv; printf(%.3lfn,L2 / midv * (1-cos(midv / 2); return 0;POJ 1064 Cable masterAC率较低的题,也是很明显的二分题,但是由于精度问题WA了很多次,最终看discuss过的,这题一个很重要的精度思想就是把每个浮点数全部变成int型,然后二分,不然会有很大的精度问题

19、,其次就是读入的时候不能用double读入,可能是因为把double转换成int时有精度的丢失吧,要用字符串读入,然后再转换成int型。#includeusing namespace std;#define MAX 10005int n,k;int aMAX;bool can(int t) int ans=0; int i; for(i=1;i=k)return true; return ans=k;void solve() if(!can(1) printf(0.00n); return ; int bottom=1,top=0; int i; for(i=1;i=n;i+) if(topa

20、i)top=ai; while(bottom1; if(can(mid)bottom=mid; else top=mid-1; double ans; if(can(top)ans=top*0.01;/求出的数乘以0.01即为答案 else ans=bottom*0.01; printf(%.2lfn,ans);int main() char str100; cinnk; int i; for(i=1;i=n;i+) scanf(%s,str);/*精度的问题,要用字符串输入* int j; ai=0; for(j=0;strj&strj!= ;j+) if(strj!=.)ai=ai*10+strj-0;/把读入的数乘以100转换成int型 solve(); return 0;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1