一:Cantor的数表
暂时不知道在哪一个oj上有相应的题,所以我只是看看这位高手的博客,就没自己写了。
这个是我抄书上的代码:
#include<stdio.h> int main() { int n; while(scanf("%d", &n) == 1) { int k = 1, s = 0; for(;;) { s += k; if(s >= n) { printf("%d/%d ", s-n+1,k-s+n); break; } k++; } } return 0; } //跑出来证明他的结果不对,因为没考虑斜行的单双数。
书上利用代数,还可以做的更好(不用循环,直接总结了一个公式),具体的自己买书去看吧~~~
二:因子和阶乘
1:书上的例题解法是先打素数表,再循环判断更新各个素因子的最大下标,然后逐个输出。
暂时没在我知道的oj上找到原题,所以我就看看过了。
题目很长,一堆废话,重点就只有几句,汗
总之就是求 阶乘n!末尾0的个数
因子5出现的次数一定比2少,因此有多少个5就有多少个10——来自discuss
傻乎乎的暴力会超时:
//For any positive integer N, Z(N) is the number of zeros at the end of the decimal form of number N!. //这句话才是题目的重点 //因子5的个数总比2多 //这样子直接模拟超时了 #include<stdio.h> int main() { int ans,t,n,m; scanf("%d",&t); while(t--) { scanf("%d",&n); ans=0; while(n) { m=n; while(m%5==0) { m=m/5; ans++; } n--; } printf("%d ",ans); } return 0; }
正解:
//改进一下 //首先要知道 5,10,15,20,25,30,…… 才有因子5 // 100/5=20(相当于把100以内所有参与阶乘的数并且凡是可以整除5的数 都除以5,并记录共整除了20次) //->20/5=4(同上,还是100以内,被上面那一步骤处理过的数并且仍旧还能整除5的数 都除以5,并再次记录共整除了4次) //那么20+4=24(上面记录的几次都相加就是100!的值中包含的因子为5的总个数) //1024/5=204 -> 204/5=40 -> 40/5=8 -> 8/5=1 //那么204+40+8+1=253 #include<stdio.h> int main() { int ans,t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); ans=0; while(n) { ans+=n/5; n=n/5; } printf("%d ",ans); } return 0; }
三:果园里的树
四:多少块土地
这两个我都没在我熟知的oj上找到对应的题,所以我就看看过了。