77范文网 - 专业文章范例文档资料分享平台

acm算法经典例题(2)

来源:网络收集 时间:2020-04-21 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

4 8 12

如上,当m=4时,只有m^1不大于n,所以结果第一个数为4,然后后面有8 12为4的倍数,且不大于n,所以得到3个结果,和例子的结果一致。

这样就成功推出了解题方法,虽然不严谨,但作为一般人,能做出来就行了。 代码:

#include using namespace std; int main() {

long long m, n, remain, id, j;//id表示下标,j表示当前第几个报数 while(cin >> n >> m, !(n == 0 && m == 0)) {

//得到不大于n的 m^x 的值 j = 1;

for(id = 1;; id++) {

j = j * m; if(j * m > n) break; }

remain = 0; for(id = 1;;id++) {

if(j * id <= n)//得到不大于n的 m的倍数 的个数 remain++; else break; }

cout << remain << endl; for(id = 1; id < remain; id++) cout << id * j << \ cout << id * j << endl; } return 0; }

5: 小数化分数 描述

Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?

请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。 输入

第一行是一个整数N,表示有多少组数据。

每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。 输出

对每一个对应的小数化成最简分数后输出,占一行。 样例输入 3 0.(4)

0.5

0.32(692307) 样例输出 4/9 1/2 17/52

思路/方法:这题需要有个数学转化方法,小编看了别人的纯循环小数转分数的方法,然后又花了点时间推出了非纯循环小数转分数方法,下面分享一下。 1.有限小数:

分子分母乘以10的次方,使得没有小数位,然后分子分母分别除以最大公约数就化简完成。比如0.4,就是0.4*10/10,最大公约数为2,化简后就是2/5 2.纯循环小数

乘以10的次方使得循环部分没有小数位,然后用该数-原数=整数部分。 所以分数形式=循环节/9...9(9的个数等于循环节数字个数)

例如:0.44..,0.444..*10-0.444..=4。所以(10-1)*0.44..=4。0.44..=4/9。 3.非纯循环小数

乘以10的次方使得循环部分没有小数位记为a*10^x,乘以10的次方使得非循环部分没有小数记为a*10^y,则a*10^x-a*10^y就消去了后面的小数。比如:0.2433..*1000-0.243..*100=243-24,所以0.243..=(243-23)/(1000-100),然后总结之后得出下面的结论。 不循环部分和循环节构成的的数 减去 不循环部分的差,再除以循环节位数个9,添上不循环部分的位数个0。比如: 0.24333333????=(243-24)/900=73/300 0.9545454????=(954-9)/990=945/990=21/22

方法有了,代码也容易写,但小编做的时候犯了一个错误,把循环部分和非循环部分全都当成整数来接受,导致丢失了位数,使得分母不准确了。比如0.001(02)这样的,当成整数接受,非循环部分是1,算长度的时候直接算就是1,循环部分接受后变成2,算长度是1,导致分母变成了90,而实际上是99000。所以必须用字符串来存储,具体看代码了。 代码:

#include #include

long long greatestCommonDivisor(long long a, long long b) {

long long t; while(b) {

t = a % b; a = b; b = t; } return a; }

int main() {

int i, n, j, k;

long long denominator, numerator, divisor, cyclical, nonCyclical;//分母分子,非循环部分和循环部分

char a[20], nonCyclicalString[20], cyclicalString[20];//必须用文本,否则会丢失位数,比如0.001010这样的会把0丢了 scanf(\ for(i = 0; i < n; i++) {

scanf(\ getchar();

if(strchr(a, '(') != NULL)//有循环小数的情况

{

if(a[0] == '(')//如果是纯循环小数 {

sscanf(a, \只能这样读取,把括号补充完整也一样的结果

cyclicalString[strlen(cyclicalString) - 1] = '\\0';//手动删除后面的括号。读取到了循环部分 sscanf(cyclicalString ,\ nonCyclicalString[0] = '\\0';

numerator = cyclical;//分子就等于循环节 } else {

for(j = 0; a[j] != '('; j++)//读取到(就停止。读取非循环部分 nonCyclicalString[j] = a[j]; nonCyclicalString[j] = '\\0';

for(k = 0, j = j + 1; a[j] != ')'; j++, k++)//从(右边一个开始读取到)就停止。读取循环部分 cyclicalString[k] = a[j]; cyclicalString[k] = '\\0';

sscanf(nonCyclicalString, \把非循环部分的值放入到变量中 sscanf(cyclicalString, \把循环部分的值放入到变量中 numerator = nonCyclical;//把分子的值先变成非循环部分

for(j = 0; cyclicalString[j] != '\\0'; j++)//往分子尾部加入循环节部分 {

numerator = numerator * 10 + (cyclicalString[j] - '0'); }

numerator = numerator - nonCyclical;//非循环部分和循环部分的组合 - 非循环部分 }

//计算分母 denominator = 0;

for(j = 0; cyclicalString[j] != '\\0'; j++)//加上循环节个数个9 denominator = denominator * 10 + 9;

for(j = 0; nonCyclicalString[j] != '\\0'; j++)//加上非循环部分个0 denominator = denominator * 10;

divisor = greatestCommonDivisor(numerator, denominator);

printf(\ }

else//非循环小数 {

sscanf(a, \把小数部分存到变量中 denominator = 1;

for(j = 0; a[j] != '\\0'; j++)//计算分母 denominator = denominator * 10;

divisor = greatestCommonDivisor(numerator, denominator);

printf(\ } } return 0; }

6: 全排列 描述

任意输入n个不重复的整数序列,输出序列的全排列。

输入

测试数据有多组,第一行是整数t(0

按递增的顺序输出序列的全排列。每个测试数据后面输出一个空行。 样例输入 1 3 1 3 5 样例输出 1 3 5 1 5 3 3 1 5 3 5 1 5 1 3 5 3 1

思路/方法:全排列有递归和非递归算法,具体网上有,这里我们为了代码简洁,采用STL里面的函数来实现,容易理解,而且好写。 首先引用algorithm这个库,然后里面有sort排序函数和next_permutation下一个排列函数。 sort升序排序,参数分别是首地址和末地址

next_permutation是判断是否有下一个排列,有返回true,并且改变数组状态,否则返回false。参数分别是首地址和末地址 代码:

#include #include using namespace std;

void display(int a[], int n) {

int i;

for(i = 0; i < n - 1; i++) cout << a[i] << \ cout << a[i] << endl; }

void fullPermutation(int a[], int n)//全排列,STL实现 {

sort(a, a + n);//升序排序 do {

display(a, n);//显示出来 }while(next_permutation(a, a + n)); }

int main() {

int i, n, t, j; cin >> t;

for(i = 0; i < t; i++) {

cin >> n; int a[n];

for(j = 0; j < n; j++) cin >> a[j]; fullPermutation(a, n);

cout << endl; } return 0; }

7: (1+x)^n 描述

Please calculate the coefficient modulo 2 of x^i in (1+x)^n. 输入

For each case, there are two integers n, i (0<=i<=n<=2^31-1) 输出

For each case, print the coefficient modulo 2 of x^i in (1+x)^n on a single line. 样例输入 3 1 4 2 样例输出 1 0 翻译: 描述

请计算(1+x)^n中x^i的系数对2取模的值 输入

每组测试数据有两个整数n i (0<=i<=n<=2^31-1) 输出

每组输出一行,即对2取模的值

思路/方法:(1 + x)^n展开后x^i项的系数的对2取余 即求 c(n, i)x^i中的c(n, i) % 2的值

如果我们计算组合数在对2取余,就会超时,所以我们需要更简便的算法 既然是对2取模,就是奇偶性咯,所以我们需要一个组合数的奇偶性判断的算法 对于组合数C(n, m) 如果(n&m) == m,那么该组合数是奇数,否则为偶数 代码:

#include int main () {

long long n, i;

while(scanf(\ if((n&i) == i)//奇数,输出1 printf(\ else

printf(\ return 0; }

8: Summing divisors 描述

In the 18th century, L. Euler invented a function he called sigma to study properties of whole numbers. He was interested in comparing a positive number to the sum of its positive divisors. In this problem we extend Euler's function to fractions. Given a positive rational number (i.e., a fraction) in simplest terms a/b, we define S(a/b) to be the sum of all positive numbers of the form x/y where x is a positive divisor of a and y is a positive divisor of b. For example, the positive

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库acm算法经典例题(2)在线全文阅读。

acm算法经典例题(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/1006567.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: