ACM必做50题——数学
acm数学竞赛试题

acm数学竞赛试题
ACM数学竞赛试题通常涉及各种数学领域,包括但不限于代数、几何、概率统计和组合数学等。
以下是一些经典的ACM数学竞赛试题:
1. 平面上n个点的k距离和最小值问题:给定平面上n个点,对于每个点,计算它到其他所有点的距离,然后求出这些距离中的k个最小值。
问题是:如何有效地计算这k个最小值?
2.最长公共子序列问题:给定两个序列,找出它们的最长公共子序列。
例如,对于序列
A = [1, 2, 3, 4] 和
B = [2, 3, 4, 5],最长公共子序列是[2, 3, 4]。
3. 凸包问题:给定平面上的一组点,找到一个最小的凸多边形,使得这个多边形能够包含这组点中的所有点。
4. 最短路问题:给定一个有向图,其中每条边都有一个非负的权重,找出图中任意两点之间的最短路径。
5. 子集和问题:给定一个正整数数组和一个目标值,判断数组中是否存在和为目标值的两个非空子集。
例如,给定数组[1, 2, 3, 4] 和目标值7,判断是否存在两个子集,它们的和分别为7。
以上只是ACM数学竞赛试题的一部分,实际上还有更多涉及数学各个领域的题目。
要提高解决这类问题的能力,需要不断练习和研究。
ACM题库完整版

#include<stdio.h> int type(int); char week[7][10]={"saturday","sunday","monday","tuesday","wednesday","thursday","friday"}; int year[2]={365,366}; int month[2][12]={31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,31,30,31,31,30,31,30,31}; int main(void) { int days,dayofweek; int i=0,j=0; while(scanf("%d",&days)&&days!=-1) { dayofweek=days%7; for(i=2000;days>=year[type(i)];i++) days-=year[type(i)]; for(j=0;days>=month[type(i)][j];j++) days-=month[type(i)][j]; printf("%d-%02d-%02d%s\n",i,j+1,days+1,week[dayofweek]); } return 0; } int type(int m) { if(m%4!=0||(m%100==0&&m%400!=0)) return 0; else return 1; }
登山
1.题目描述 五一到了,NUIST-ACM队组织大家去登 山观光,队员们发现山上一个有N个景点, 并且决定按照顺序来浏览这些景点,即 每次所浏览景点的编号都要大于前一个 浏览景点的编号。同时队员们还有另一 个登山习惯,就是不连续浏览海拔相同 的两个景点,并且一旦开始下山,就不 再向上走了。队员们希望在满足上面条 件的同时,尽可能多的浏览景点,你能 帮他们找出最多可能浏览的景点数么? 2.输入 Line 1: N (2 <= N <= 1000) 景点数 Line 2: N个整数,每个景点的海拔 3.输出 最多能浏览的景点数 4.样例输入 8 186 186 150 200 160 130 197 220 5.样例输出 4
(2020年编辑)ACM必做50题的解题-数论

poj 1061 青蛙的约会这题用的是解线性同余方程的方法,之前没接触到过,搜索资料后看到一个人的博客里面讲的很好就拷贝过来了。
内容如下:对于方程:ax≡b(mod m),a,b,m都是整数,求解x 的值,这个就是线性同余方程。
符号说明:mod表示:取模运算ax≡b(mod m)表示:(ax - b) mod m = 0,即同余gcd(a,b)表示:a和b的最大公约数求解ax≡b(mod n)的原理:对于方程ax≡b(mod n),存在ax + by = gcd(a,b),x,y是整数。
而ax≡b(mod n)的解可以由x,y来堆砌。
具体做法如下:第一个问题:求解gcd(a,b)定理一:gcd(a,b) = gcd(b,a mod b)欧几里德算法int Euclid(int a,int b){if(b == 0)return a;elsereturn Euclid(b,mod(a,b));}附:取模运算int mod(int a,int b){if(a >= 0)return a % b;elsereturn a % b + b;}第二个问题:求解ax + by = gcd(a,b)定理二:ax + by = gcd(a,b)= gcd(b,a mod b) = b * x' + (a mod b) * y'= b * x' + (a - a / b * b) * y'= a * y' + b * (x' - a / b * y')= a * x + b * y则:x = y'y = x' - a / b * y'以上内容转自/redcastle/blog/item/934b232dbc40d336349bf7e4.html由这个可以得出扩展的欧几里德算法:int exGcd(int a, int b, int &x, int &y) {if(b == 0){x = 1;y = 0;return a;}int r = exGcd(b, a % b, x, y);int t = x;x = y;y = t - a / b * y;return r;}代码:#include<iostream>#include<cstdlib>#include<cstring>#include<cmath>using namespace std;__int64 mm,nn,xx,yy,l;__int64 c,d,x,y;__int64 modd(__int64 a, __int64 b){if(a>=0)return a%b;elsereturn a%b+b;}__int64 exGcd(__int64 a, __int64 b) {if(b==0){x=1;y=0;return a;}__int64 r=exGcd(b, a%b);__int64 t=x;x=y;y=t-a/b*y;return r;}int main(){scanf("%I64d %I64d %I64d %I64d %I64d",&xx,&yy,&mm,&nn,&l);if(mm>nn) //分情况{d=exGcd(mm-nn,l);c=yy-xx;}else{d=exGcd(nn-mm,l);c=xx-yy;}if(c%d != 0){printf("Impossible\n");return 0;}l=l/d;x=modd(x*c/d,l); ///取模函数要注意printf("%I64d\n",x);system("pause");return 0;}POJ 1142 SmithNumber题意:寻找最接近而且大于给定的数字的SmithNumber什么是SmithNumber?用sum(int)表示一个int的各位的和,那一个数i如果是SmithNumber,则sum(i) =sigma( sum(Pj )),Pj表示i的第j个质因数。
ACM试题及参考答案

1. 给定一个矩阵M(X, Y),列集为X ,行集为Y 。
如果存在对其列的一个排序,使得每一行的元素都严格递增,称M 是一个次序保持矩阵。
例如下图中存在一个排序x 4,x 1,x 2,x 3,x 5I ⊆X ,满足:子矩阵M(I,Y)是次序保持矩阵。
[测试数据] 矩阵M :[测试数据结果] I={ x 1,x 3,x 4,x 7,x 8}[解题思路] 将该问题归约为在一个有向图中找一条最长路径的问题。
给定矩阵M=(a ij ),行集Y ,列集X ,行子集J ⊆Y ,定义有向图D A =(V A ,E A ),其中V A 含有|X|个顶点,每个顶点代表X 中的一列,如果顶点u ,v 对应的列x u ,x v 满足,对于任意的j ∈J ,u v ij ij a a <,则有一条从u 到v 的弧(u ,v )∈E 。
显然,D A 是个无环图,可以在O(|X|2)时间内构造完毕。
对于任意的条件子集J ,A(I,J)是次序保持的当且仅当对应于J 中条件的顶点在D A 中构成一条有向路径。
从而我们只需在有向图D A 中找一条最长路径,该问题可在O(|V A |+| E A |)时间内完成。
按上面的方法构造有向图如下:有向图中找最长路径的线性时间算法。
一些表示方法如下:d out (u )为顶点u 的出度,d in (u )为顶点u 的入度,source 为入度为0的顶点,sink 为出度为0的顶点,N out (u )为u 指向的邻接点集合,P uv 为从u 到v 的最长路,显然应从source 到sink 。
在每一步为每个顶点关联一个永久的或临时的标签。
v被赋了一个临时标签(v’,i v)表明在当前步,算法找出的最长的从source到v的有向路长度为i v,且经由v’而来。
v被赋了一个永久标签[v’,i v]表明从source到v的最长有向路长度为i v,且经由v’而来,通过回溯每个顶点的永久标签就可以找出最长有向路。
ACM必做50题——动归

1 动态规划——POJ 2479 Maximum sum我觉得这个题目跟2593是一样的题目,就是数据量有些不同。
这个题目数据量是50000,但时间只有1000ms,而2593数据量有100000,但时间有3000ms,所以相对而言,这个题目对算法的要求还要高一些,也难怪好多人都在后面发贴说过了2593但这个却没过得了。
考查点:动态规划思路:在输入的同时,进行一次DP,计算出从左到右的最大值,并把它保存在数组dp的对应的下标元素中,这样之后,对于下标为i的元素,它其中保存的便是前面所有元素可能的最大连续和。
再从右到左进行一次DP,计算从右到左的最大连续和。
假设此时已经算到下标为i的元素,那么将sum+dp[i-1]与ans进行比较,将ans取较大者。
最后当i到2的时候ans中的值即为所求的最大值。
提交情况:记不清是多少Wrong Answer,但肯定是有一次Time Limit Error,因为我有用O(N^2)的DP做过,而且可以通过我想到的所有测试数据。
收获:对动态规划问题如何更好地减少时间有了一点点理解,也复习了一下基本的技能。
经验:做题之前做好充分地分析,包括时间效率、空间效率以及实现地难度。
TLE Code(O(N^2)):(自己想了好久才想出来的,给自己鼓励一下)#include <iostream>using namespace std;int array[50001], num[50001];const int MIN = -999999999;int main(){int tcase, n;cin>>tcase;int tmp, ans, i, sum;while(tcase--){scanf("%d", &n);tmp = MIN; sum = 0;for(i = 1; i <= n; i++){scanf("%d", &num[i]);sum += num[i];if(sum > tmp)tmp = sum;array[i] = tmp;if(sum < 0)sum = 0;}tmp = ans = MIN;sum = 0;for(i = n; i > 1; i--){sum += num[i];if(sum > tmp)tmp = sum;if(ans < (array[i-1]+tmp))ans = array[i-1]+tmp;if(sum < 0)sum = 0;}cout<<ans<<endl;}return 0;}2 POJ 2593 Max Sequence考察点:动态规划思路:虽然题目给出了3000ms的时间,但考虑到数据量可以达到100000,如果用O(N^2)的算法的话,还是极有可能会超时的,于是决定采用这种O(N)时间效率的动规。
最新acm入门简单数学题(精品ppt课件

06.01.2021
28
请自己仔细分析...
哪位同学做个陈述?
06.01.2021
29
课后任务:
完成在线练习:
201309《ACM程序设计》作业(2)—— 刘春英 老师
特别提醒:
作业务必尽力完成(第一次的作 业尚未完成的,一定要补上~)
作业密码:helloworld
06.01.2021
30
Welcome to HDOJ
Thank You ~
06.01.2021
31
公民反恐防范知识宣 资料
(宜宾市反恐办宣)
1.如何识别恐怖嫌疑人员?
• (1)神情慌张,言行异常者; • (2)着装、携带物品与其身份明显不符,服装奇异; • (3)携带有管制刀具、斧头以及类似爆炸物等危险物品 • (4)频繁进出大型活动场所,反复在商场、医院、车站
ACM入门简单数学题(精品)
今天,
你 了吗?
06.01.2021
2
很常见的一种写法:
#include<stdio.h>
int main()
{ int n, i, sum=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
sum=sum+i;
printf("%d\n",sum);
}
06.01.2021
23
HDOJ_1005: Number Sequence
06.01.2021
24
Question:
暴力(Brute-Force) 能解决问题吗?
ACM竞赛基础训练题.docx

ACM竞赛基础训练题H【题目]】N皇后问题(八皇后问题的扩展)【题ri 2】排球队员站位问题【题H 3]把自然数N分解为若干个自然数之和。
【题H 4]把自然数N分解为若干个自然数之积。
【题H 5】马的遍历问题。
【题H 6】加法分式分解【题H 7】地图着色问题【题H 8]在n和的正方形屮放置长为2,宽为1的长条块,【题H 9】找迷宫的最短路径。
(广度优先搜索算法)【题Fl 10]火车调度问题【题H 11]农夫过河【题FI 12]七段数码管问题。
【题H 13]把1-8这8个数放入下图8个格中,要求相邻的格(横,竖,对角线)上填的数不连续. 【题FI 14]在4X4的棋盘上放置8个棋,要求每一行,毎一列上只能放置2个.【题H 15]迷宫问题.求迷宫的路径.(深度优先搜索法)【题H 16]一笔画问题【题H 17]城市遍历问题.【题H 18]棋子移动问题【题H 19]求集合元索问题(l,2x+l,3X+l类)【题RI N皇后问题(含八皇后问题的扩展,规则同八皇后):在N粒的棋盘上, 放置N个皇后,要求每一横行每一列,每一对角线上均只能放置一个皇后,问可能的方案及方案数。
const max=8;var i,j:integer;a: array [1.. max] of 0.. max; {放皇后数组}b:array[2.. 2*max] of boolean; {/对角线标志数组}c:array[-(max-1).. max-1 ] of boolean; {\对角线标志数组}col:array [1.. max] of boolean; {列标志数组}total: integer; {统计总数}procedure output; {输出}var i:inte^er;beginwrite (' No.' :4,' [', total+1:2,']');for i :=1 to max do write (a [i] :3) ;write(, ');if (to tal+1) mod 2 =0 t hen writ eln; inc (to tai);end;function ok(i, dep: integer) :boolean; {判断第dep 行第i 列可放否}begin ok:=false;if ( b[i+dep]二true) and ( c[dep-i]二true) {and (a[dep]=0)} and(col[i]=true) then ok:二trueend;procedure try (dep:integer);var i,j:integer;beginfor i:=l to max do 侮一行均有max种放法}i f ok (i, dep) then begi na [dep]:=i;b[i+dep]:二false; {/对角线已放标志}c[dep-i]:二false; {\对角线已放标志}col [i]:二false; {列已放标志}if dep二max then outputelse try (dep+1) ; {递归下一层}a[dep] :=0; {取走皇后,回溯}b[i+dep]:二true; {恢复标志数组}c[dep-i]:二true;col[i]:二true;end;end;beginfor i:=1 to max do begin a[i]:=0;col[i]:=true;end;for i:=2 to 2*max do b[i]:二true;for i:=-(max-1) to max~l do c[i]:=true;total:二0;try(l); writelntotal , total);end.【测试数据】n二8八皇后问题No.[ 1] 1 5 8 6 3 7 2 4 No. [ 2] 1 6 83 7 4 2 5 No.[ 3] 1 7 4 6 8 2 5 3 No. [ 4] 1 7 58 2 4 6 3 No.[ 5] 2 4 6 8 3 1 7 5 No. [ 6] 2 5 71 3 8 6 4 No.[ 7] 2 5 7 4 1 8 6 3 No. [ 8] 2 6 17 4 8 3 5 No.[ 9] 2 6 8 3 1 4 7 5 No. [10] 2 7 36 8 5 1 4No. [11] 2 7 5 8 1 4 6 3 No. [12] 2 8 61 3 5 7 4 No. [13] 3 1 7 5 8 2 4 6 No. [14] 3 5 28 1 7 4 6 No. [15] 3 5 2 8 6 4 7 1 No. [16] 3 5 71 4 2 8 6 No. [17] 3 5 8 4 1 7 2 6 No. [18] 3 6 25 8 1 7 4 No. [19] 3 6 2 7 1 4 8 5 No. [20] 3 6 27 5 1 8 4 No. [21] 3 6 4 1 8 5 7 2 No. [22] 3 6 42 8 5 7 1 No. [23] 3 6 8 1 4 7 5 2 No. [24] 3 6 81 5 7 2 4 No. [25] 3 6 8 2 4 1 7 5 No. [26] 3 7 28 5 1 4 6 No. [27] 3 7 2 8 6 4 1 5 No. [28] 3 8 47 1 6 2 5 No. [29] 4 1 5 8 2 7 3 6 No. [30] 4 1 58 6 3 7 2 No. [31] 4 2 5 8 6 1 3 7 No. [32] 4 2 73 6 8 1 5 No. [33] 4 2 7 3 6 8 5 1 No. [34] 4 2 75 1 8 6 3 No. [35] 4 2 8 5 7 1 3 6 No. [36] 4 2 86 1 3 5 7 No. [37] 4 6 1 5 2 8 3 7 No. [38] 4 6 82 7 1 3 5 No. [39] 4 6 8 3 1 7 5 2 No. [40] 4 7 18 5 2 6 3 No. [41] 47 3 8 2 5 1 6 No. [42] 4 7 52 6 1 3 8 No. [43] 4 7 5 3 1 6 8 2 No. [44] 4 8 13 6 2 7 5 No. [45] 4 8 1 5 7 2 6 3 No. [46] 4 8 53 1 7 2 6 No. [47] 5 1 4 6 8 2 7 3 No. [48] 5 1 84 2 7 3 6 No. [49] 5 1 8 6 3 7 2 4 No. [50] 5 2 46 8 3 1 7 No. [51] 5 2 47 3 8 6 1 No. [52] 5 2 61 7 48 3 No. [53] 5 2 8 1 47 3 6 No. [54] 5 3 16 8 2 4 7 No. [55] 5 3 1 7 28 6 4 No. [56] 5 3 84 7 1 6 2 No. [57] 5 7 1 3 8 6 4 2 No. [58] 5 7 14 2 8 6 3 No. [59] 5 7 2 4 8 1 3 6 No. [60] 5 7 26 3 1 4 8 No. [61] 5 7 2 6 3 1 8 4 No. [62] 5 7 41 3 8 6 2 No. [63] 5 8 4 1 3 6 2 7 No. [64] 5 8 41 7 2 6 3 No. [65] 6 1 5 2 8 3 7 4 No. [66] 6 2 71 3 5 8 4 No. [67] 6 2 7 1 4 8 5 3 No. [68] 6 3 17 5 8 2 4 No. [69] 6 3 1 8 4 2 7 5 No. [70] 6 3 18 5 2 4 7 No. [71] 6 3 5 7 1 4 2 8 No. [72] 6 3 58 1 4 2 7 No. [73] 6 3 7 2 48 1 5 No. [74] 6 3 72 8 5 1 4 No. [75] 6 3 7 4 1 8 2 5 No. [76] 6 4 15 8 2 7 3 No. [77] 6 4 2 8 5 7 1 3 No. [78] 6 4 71 3 5 2 8 No. [79] 6 4 7 1 8 2 5 3 No. [80] 6 8 24 1 7 5 3 No. [81] 7 1 3 8 6 4 2 5 No. [82] 7 2 41 8 5 3 6 No. [83] 7 2 6 3 1 4 8 5 No. [84] 7 3 16 8 5 2 4 No. [85] 7 3 8 2 5 1 6 4 No. [86] 7 4 25 8 1 3 6 No. [87] 7 4 2 8 6 1 3 5 No. [88] 7 5 31 6 8 2 4 No. [89] 8 2 4 1 7 5 3 6 No. [90] 8 2 53 1 7 4 6 No. [91] 8 3 1 6 2 5 7 4 No. [92] 8 4 13 6 2 7 5 total:92 对于N皇后:【题H 】排球队员站位问题I ----------------- 1图为排球场的平面图,其屮一、二、三、四、五、六为位 置编号, I |二、三、四号位置为前排,一、六、五号位为后排。
acm算法经典例题

acm算法经典例题一、数论1: Wolf and Rabbit描述There is a hill with n holes around. The holes are signed from0 to n-1.A rabbit must hide in one of the holes. A wolf searches the rabbit in anticlockwise order. The first hole he get into is the one signed with 0. Then he will get into the hole every m holes. For example, m=2 and n=6, the wolf will get into the holes which are signed 0,2,4,0. If the rabbit hides in the hole which signed 1,3 or 5, she will survive. So we call these holes the safe holes.输入The input starts with a positive integer P which indicates the number of test cases. Then on the following P lines,each line consists 2 positive integer m and n(0<m,n<2147483648).< bdsfid="69" p=""></m,n<2147483648).<>输出For each input m n, if safe holes exist, you should output "YES", else output "NO" in a single line.样例输入21 22 2样例输出NOYES翻译:描述一座山有n个洞,洞被标记为从0到n-1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、POJ 2249 Binomial Showdown组合数学。
高精度,也可把分子分母的数组进行两两约分#include<iostream>using namespace std;double c(int c,int k){double a=1;int i,j=2;for(i=c;i>c-k;i--)a=a*i/(c-i+1);return a;}int main(){int n,k;while(scanf("%d%d",&n,&k)!=EOF && (n!=0 || k!=0)){if(k>n/2 )k=n-k;printf("%.0lf\n",c(n,k));}return 0;}2、poj 1023 the fun number system (经典进位制)题意:一种由2进制衍生出来的进制方法(我们暂且称为“类2进制”);标明'n'的位置上原2进制该位的权重要乘上-1,才是现在进制方法该位的权重;譬如说;pnp对于的能表示的数2来说就是110;即1*2^2+(-1)*1*2^1+1*2^0=2;算法:这是数论中的进位制问题,我们可以仿照原来的求一个数二进制表示方法;但首先,我们应该考虑几个问题;①k位这种类2进制的表示范围;显然,当给出的'p','n'序列中,我们将所有p的位置都置为1其余位是0,此时最大;当我们将所有n的位置置为1,其余为0,此时最小;不过当我们求最大限max和最小限min时会有一个溢出问题;比如64位全是p的序列,那么max会溢出,值为-1;同理min在全是n 时也会溢出,为1;显然是max>=0,min<=1,溢出时产生异常,依次可以判断;②是否是最大限和最小限之间的数都能表示呢?都可以,而且能够表示的数是2^k个,这个原始2进制是一样的;因为每个位上要么是0,要么是1,而且每个位上的权重唯一的,不能通过其他位的01组合获得;最后,我们就可以仿照原始二进制来算在类2进制下的表示;不断求N的二进制最后一位和右移;如果取余是1,则该位上一定是1,如果该位对于字母为‘n’,则高位应该再加1;这里对2取余可能会出错,因为对于负数,补码的表示,最后一位一定是和原码一样的每次的右移后(有时需先加1)补码表示正好符合要求(可找实例验证);#include<iostream>using namespace std;__int64 N,M;char s[100],res[100]={'\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;i<N;i++) //找出能表示的范围;{if(s[i]=='p') _max=2*_max+1,_min*=2;else _min=2*_min-1,_max*=2;}scanf("%I64d",&M);if((M<_min&&_min<=0)||(M>_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;{res[i]='1';if(s[i]=='n') flag=1;}else res[i]='0';M>>=1;if(flag) M++; //如果是n就需其高位加1;}printf("%s\n",res);}}system("pause");return 0;}3、POJ2506 Tiling 递推+高精给看似复杂的题找到了合适的规律就会变得简单。
这个题就是这样。
对于n列来说,可以在n-1列的基础上加上一块,或者是在n-2列的基础上加上2块而2块独立的,不依赖于1块的情况有两种,所以得到递推公式f(n)=f(n-1)+2f(n-2)看样例,要用到高精。
#include<iostream>//f(n)=f(n-1)+2f(n-2)using namespace std;int f[251][300];void HPprint(int *a){for (int i=a[0];i>=1;i--) cout<<a[i];cout<<endl;}void HPplus(int *a,int *b,int *c){int i,j;j=0;for(i=1;i<=min(a[0],b[0]);i++){c[i]=a[i]+b[i]+j;j=c[i]/10;c[i]%=10;}if(j!=0) c[i]=j;c[0]=a[0]>b[0]?a[0]+2:b[0]+2;while(c[c[0]]==0 && c[0]>1) c[0]--;}void HPmultyNUM(int *a,int b,int *c) {int i,j,k;for (i=1;i<=a[0];i++)c[i]+=a[i]*b;k=0;for (j=1;j<=a[0];j++){c[j]+=k;k=c[j]/10;c[j]%=10;}//进位if(k!=0) c[j]=k;c[0]=a[0]+3;while (c[c[0]]==0 && c[0]>1) c[0]--; }int main(){int i,j,t[300],test;f[0][0]=1;f[0][1]=1;f[1][0]=1;f[1][1]=1;f[2][0]=1;f[2][1]=3; for(i=3;i<=250;i++){memset(t,0,sizeof(t));HPmultyNUM(f[i-2],2,t);HPplus(t,f[i-1],f[i]);}while(cin>>test)HPprint(f[test]);return 0;}4、POJ 1079 Ratio 分数操作题目大意:给出一个分数,比如1498/902。
求出当分母分别为1, 2, ....的时候,最接近1498/902的分数。
比如:当分母为1的时候,最接近1498/902的分数为1/1。
当分母为2的时候,最接近1498/902的分数为3/2。
当分母为3的时候,最接近1498/902的分数为5/3。
思路:不要用高精度哦,直接模拟分数的操作最好了。
#include <stdio.h>#include <math.h>struct frac {__int64 up, down;};__inline __int64 gcd(__int64 a, __int64 b){__int64 r;if (a < b) {r = a;a = 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){return 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("%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; down++) {up = (down*target.up)/target.down;if (((down*target.up)%target.down)*2 >= target.down)up++;f = frac_init(up, down);dis = frac_abs(frac_sub(f, target));if (frac_cmp(dis, min_dis) < 0) {printf("%I64d/%I64d\n", f.up, f.down);min_dis = dis;}}printf("\n");}return 0;}5、poj 1019 Number Sequence (找规律)找规律的题目:先计算出从1到n这个小区间有多长,保存到digit[]数组中,然后计算从112123到n一共有多少位数字,然后根据输入数据查找,其中我在找那一位时比较暴力,把从1开始一直存放,直到存放的比那一位还多,然后取出那一位。
#include <iostream>#include <sstream>#include <string>#include <cmath>using namespace std ;const int MaxSize=100000+10 ;__int64 digit[MaxSize], len[MaxSize] ;stringstream ss ;void init(){int i ;digit[1] = len[1] = 1 ;for( i=2; i<MaxSize; ++i ){digit[i] = digit[i-1] + (int)log10((double)i)+1 ;len[i] = len[i-1] + digit[i] ;}/*for( i=1; i<10; ++i ){cout << i << " 位数" << digit[i] << " 长度" << len[i] << endl ;}*/}char getDigit( int num ){int i ;for( i=1; len[i]<num; ++i );int pos = num-len[i-1] ;// 清空ssss.str("");for( i=1; i<=pos; ++i ){ss << i ;//cout << ss.str() << endl ;}return (ss.str())[pos-1] ;}int main(){int i, sets, num ;init() ;cin >> sets ;while( sets-- ){cin >> num ;cout << getDigit( num ) << endl ;}return 0 ;}6、POJ 1095 Trees Made to Order思路:首先,设拥有N个结点的不同形态的有序二叉树有L[N]棵。