数据结构与算法分析C++表述第二章编程题

  把昨天看的第二章巩固一下,做一做编程习题。

2.6:

  第一天交2元罚金,以后每一天都是前一天的平方,第N天罚金将是多少?

这个题目和2.4.4-3介绍的幂运算基本一致。若按相同的递归思路分析,比那个问题要简单,因为从1次幂开始并且指数呈2^(n-1)分布,即1,2,3,4,16……所以没有对指数是奇数时的判定。实际上用循环来求要比用递归快。在不考虑溢出的前提下,解法如下:

#include<iostream>
using namespace std;
typedef unsigned long long uint64;
uint64 r(int n){
    if(n==1){
        return 2;
    }else{
        uint64 tmp=r(n-1);
        return tmp*tmp;
    }
}

uint64 w(int n){
    int result=2;
    while(n!=1){
        result*=result;
        n--;
    }
    return result;
}

int main(){
    int n;
    cin>>n;
    cout<<r(n)<<" "<<w(n)<<endl;
}

2.20:

确定一个正整数是否是素数。这个问题可以简化一下,因为n*n>(n-1)*(n+1)。所以只需要求n是否能被2到sqrt(n)整除就可以了,这里需要注意的就是2是最小的素数:for(i=2;i<sqrt(n);i++)对2不能返回正确的结果,因为1.414<2不会进入循环。所以要先行判断:
#include<iostream>
#include<cmath>
using namespace std;
bool ispn(int n){
    if((n%2)==0){
        return false;
    }else{
        int i,max=int(sqrt(n));
        for(i=3;i<=max;i++){
            if((n%i)==0) return false;
        }
    }
    return true;
}

int main(){
    int n;
    cin>>n;
    cout<<ispn(n)<<endl;
}

当然,也可以if(n==2)然后for(i=2;i<=max;i++)。需要注意的是平方根(max)的条件不是小于,是小于等于。接下来有一个厄拉多塞筛的时间复杂度问题,这里仅记录厄拉多塞筛:取从2到n,n>=2之间的全部素数只需要滤掉那些非素数。根据前面讲述的原理,去掉这些非素数的方法如下:循环去掉2-sqrt(n)之间的全部非素数:

#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
typedef unsigned long long uint64;
void es(vector<int> &arr){
    int i,j,n=arr.size(),sqrtnum=int(sqrt(n));
    for(i=2;i<=sqrtnum;i++){        //从最小的素数m(m=2)开始遍历到sqrt(arr.size())
        if(arr[i]==0){                    //找到后面第一个素数m(标记仍然为0的)
            for(j=i*2;j<=n;j+=i){    //标记m*n(1<n<=arr.size/m)为非素数。
                arr[j]=1;
            }
        }
    }
}
int main(){
    int i,n;
    cin>>n;
    vector<int> arr(n+1);
    es(arr);
    for(i=2;i<=n;i++){
        if(arr[i]==0){
            cout<<i<<endl;
        }
    }
}

注意以下几点(设n为上限):

1、代码中arr默认值为0,用以表示假定为素数,最终结果中被标志为1的都不是素数;其下标与数字一一对应,即若输入11,则数组最大下标为11,亦即数组元素为n+1个。

2、根据前面的结论,i只需要从2搜索到sqrt(n),包含sqrt(n)。

3、在进行标志时,从当前素数的2倍开始标志。

在chinaunix上面看到一篇类似的算法,1、2都犯了,只能低效的输出n-1以内的,漏掉了n。例如输入11,得到的是2、3、5、7,例如输入2什么也没出来。

歇一歇,2017年1月1日12:45,以上。

时间: 2024-08-23 23:29:18

数据结构与算法分析C++表述第二章编程题的相关文章

java第四章编程题(初学篇)

代码: 1 /* 2 test.java 3 */ 4 package test; 5 public class test { 6 public static void main(String args[] ) 7 { 8 CPU ccp= new CPU(); 9 HardDisk hhd=new HardDisk(); 10 PC pc =new PC(); 11 ccp.setSpeed(2200); 12 hhd.setAmount(200); 13 pc.setCPU(ccp); 14

java学习之第五章编程题示例(初学篇)

1 /* 2 Animal.java 3 */ 4 package animal; 5 6 public abstract class Animal { 7 public abstract void cry(); 8 public abstract String getanimalName(); 9 } 1 //Dog.java 2 package animal; 3 4 public class Dog extends Animal 5 { 6 7 String aa="旺旺"; 8

2017年校招全国统一模拟笔试(第二场)编程题集合-牛客网

 2017年校招全国统一模拟笔试(第二场)编程题集合-牛客网 链接:https://www.nowcoder.com/questionTerminal/276712b113c6456c8cf31c5073a4f9d7来源:牛客网 牛牛有两个字符串(可能包含空格),牛牛想找出其中最长的公共连续子串,希望你能帮助他,并输出其长度. 输入描述: 输入为两行字符串(可能包含空格),长度均小于等于50. 输出描述: 输出为一个整数,表示最长公共连续子串的长度. 输入例子: abcde abgde 输出例子

算法导论第2章编程题自选

系列地址:算法导论(CLRS)参考答案与配套编程题选 练习2.3-7 配套编程题 :两数之和 (Two Sum) - LeetCode / LeetCode-CN 原文地址:https://www.cnblogs.com/accepteddoge/p/8718095.html

C和指针第二章编程练习

1.编写一个程序,它由3个函数组成,每个函数分别保存在一个单独的源文件中.函数increment接受一个整形参数,它的返回值是该参数的值加1.increment函数应该位于文件increment.c中.第二个函数称为negate,它也接受一个整形参数,它的返回值是该参数的负值.最后一个函数是main,保存于文件main.c中,它分别用参数10,0,-10调用另外两个函数,并打印错误. int increment(int n) {     return n+1; } int negate(int 

C Primer Plus (第五版) 第二章 编程练习

编写一个程序,调用printf()函数在一行上输出您的名和姓,再调用一次printf()函数在两个单独的行上输出您的名和姓,然后调用一对printf()函数在一行上输出您的名和姓.输出应如下所示(当然里面要换成您的姓名): Anton Bruckner    第一个输出语句 Anton        第二个输出语句 Bruckner       仍然第二个输出语句 Anton Bruckner    第三个和第四个输出语句 #include <stdio.h> int main(void) {

《数据结构与算法分析》第四章--树 (1)

4.1 预备知识 定义: 树的递归定义:一棵树是一些节点的集合,这个集合若为空集:否则由一个根结点以及该节点的0个或者若干个非空子树组成,这些子树都与该根节点有边连接. 树叶:没有子节点的节点. 兄弟(Siblings):有相同父亲节点的节点. 节点n1到nj的路径:一个节点 序列:n1,n2...,nj. 路径的长:路径上的边数. 节点ni的深度:根节点到ni的唯一路径的长.根节点深度为0. 节点ni的高度:该节点ni到叶子节点的最长路径.树的高:根节点的高度. 4.1.1 树的实现 左孩子右

c++primer 第二章编程练习答案

2.7.1 #include<iostream> int main() { using namespace std; char name[20]; char address[20]; cout << "input name :"; cin >> name; cout << "input address:"; cin >> address; cin.get(); cout << "nam

第二章编程练习题2.8

import java.util.Scanner; public class Main7 { public static void main(String[] args) { Scanner input = new Scanner(System.in); int number = input.nextInt(); System.out.println((char)number); } }