zoukankan      html  css  js  c++  java
  • 作业1 2020

    1.作业头

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/CST2020-3
    这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2020-3/homework/11768
    我在这个课程的目标是 回顾数据类型和表达式 文件
    学号 20209031
    ps: 优化写在最末尾

    二、本周作业(总分:50分)

    2.1 题目:给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数。

    例如:

    N=2,写下1,2。这样只出现了1个”1“。

    N=12,我们会写下1,2,3,4,5,6,7,8,9,10,11,12。这样,1的个数是5。

    问题是:

    1.写出一个函数f(N),返回1到N之间出现的”1“的个数,比如f(12)=5;

    2.满足条件”f(N)=N“的最大的N是多少?

    要求:

    1.贴出代码图片,写出解题思路,列出测试数据(5分)

    解题思路:通过1到n的循环逐次判断并累加count变量
    测试数据 结果
    12 5
    3594 2120
    9999 4000
    2.给出不同测试数据的运算时间,如果你的运算时间不变,说明你的测试数据不够大(5分)
    2.2 将上题中多组测试数据写入文件,并给出测试程序以检测你的代码有没有问题,贴出你的代码、运行结果和文件内容。(5分)

    2.3 用自己的语言回答两个问题,并给出所查阅资料的引用(10分)
    1.什么是文件缓冲系统?工作原理如何?

    1.指针对原件进行管理和访问以减少对磁盘的实际读写次数.
    2.系统会自动的在内存区为每一个正在使用的文件开辟一块缓冲区。从此盘向内存读数据时,则一次将一些数据从磁盘文件送内存缓冲区(充满缓冲区),然后再从缓冲区逐个将数送给接收变量(文件描述
    符);从内存写数据到磁盘文件时,现将数据塞满缓冲区,在一次性将数据从缓冲区送到磁盘文件
    

    2.什么是文本文件和二进制文件?

    1.文本文件是一种计算机文件,将键入的文档存储为一系列字母和数字字符,通常没有可视化的格式化信息。直接翻译成人类可读的文本。
    2.二进制文件是由一批同一类型的数据组成的一个数据序列,就是说一个具体的二进制文件只能存放同一种类型的数据。由计算机直接解释。
    

    2.4 请给出本周学习总结(15分)
    1 学习进度条(5分)

    周/日期 时间 代码行数 学习内容 疑惑
    1/3.3 20 200 文件 数据结构 文件 数据结构
    2 累积代码行和博客字数(5分)

    3 学习内容总结和感悟(5分)
    数据结构的学习需要耗费大量的时间 并多次实践 在算法的学习上要更家巩固基础

    思考针对足够大的数据,如何减少运算时间,并给出在原有算法基础上的改进算法和改进思路。(10分)

    思路:当数据非常大的时候,利用for循环进行枚举判断的暴力解法会让时间复杂度变得非常大 所以列举多个数字欲模拟程序以找出数学规律顺序
    例如将1-100当中的含有1的数字列举出来
    1 10 11(11含有两个1) 12 13 14 15 16 17 18 19 21 31 41 51 61 71 81 91 100 共计21个1
    按照个位十位百位划分
    个位中有1的数字: 1 11 21 31 41 51 61 71 81 91
    十位中有1的数字: 10 11 12 13 14 15 16 17 18 19
    百位中有1的数字: 100
    则猜测若列举 1-1000的数字
    1-10中 个位数中 1出现1次
    1-100中 十位数中 1出现10次
    1-1000中 百位数中 1出现100次
    如 列举1234
    个位满十进十 每1-10中 个位数中 1出现1次 从1-1230包含123个10 则1出现123次 又个位上的4>1 则包含有一个个位上的1 共123+1=124次
    十位满十进百 每1-100中 十位数中 1出现10次 从1-1200中出现12个100 则1出现120次 十位上3>1 则包含有一个十位上的(10-19)10个1 共130次
    百位满十进前 每1-1000中 百位数中 1出现100次 从1-1000中共1一个1000 则1又出现100次 百位上2>1 则包含一个百位数上的(100-200)100个1 共200次
    千位上 没有更高位数 1=1,所以1000-1234所有的千位都含有1 共出现235个(1000也包含1)
    共689个1
    例举 5678
    个:567+1=568
    十:560+10=570
    百:500+100=600
    千:1000
    共2738


    总结规律得到
    以1234为例
    右数第i个数字与1比较 若i>1 则以(i左边的数字)+ 10的(i-1)次方 若i=1则以(左边的的数字)+(右边的数字)+1
    以此数学规律为思路 优化算法并实现代码

    #include<iostream>
    #include<time.h>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    int seek(int n) {
    int a[100] = { 0 };
    int p = n, count = 0;;
    while (p != 0) {
    a[count] = (p % 10);
    p /= 10;
    count++;
    }
    int i = 0;
    int sum=0;
    while (count != 0) {
    int l = (n / pow(10, i + 1));
    l = l *pow(10, i);
    if (a[i] > 1) {
    sum +=l+pow(10,i);
    }
    if (a[i] == 1) {
    if (count == 1) {
    sum += 0 + (n - a[i] * pow(10, 3)) + 1;
    }
    else {
    sum += l + (n - l * 10) + 1;
    }
    }
    i++;
    count--;
    }
    cout << sum<<endl;
    return 0;
    }
    int main(void) {
    int n;
    clock_t begin, end;
    begin = clock();
    cin >> n;
    seek(n);
    end = clock();
    double time = (double)(end - begin) / CLOCKS_PER_SEC;
    cout << "time =" << time << "s" << endl;
    return 0;
    }
    

    然后数值过大导致pow的指数过高 超过了int类型 数值太小i和count又导致数组越界 放弃这种思路了

    因为个位十位百位等等的拆分 联想到了汉诺塔的递归 可以归结为两种 1.个位和其他位置
    1出现的次数为 (个位1出现次数)+(十位1出现次数)+(百位1出现次数)qishi
    其实和上面的思路有大部分相同 只是把分割换成了逐位(个十百)

    #include<iostream>
    #include<time.h>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    void seek(int n) {
        int count = 0;
        int base = 1;
        int round = n;
        while (round > 0) {
            int weight = round % 10;
            round /= 10;
            count += round * base;
            if (weight == 1)
                count += (n % base) + 1;
            else if (weight > 1)
                count += base;
            base *= 10;
        }
        cout << count<<endl;
    }
    int main(void) {
    	int n;
    	clock_t begin, end;
    	begin = clock();
    	cin >> n;
    	seek(n);
    	end = clock();
    	double time = (double)(end - begin) / CLOCKS_PER_SEC;
    	cout << "time =" << time << "s" << endl;
    	return 0;
    }
    

    最大N

    根据题目要求 正整数N 所以利用while控制循环条件为0-2147483647进行循环



    最大N:1111111110

  • 相关阅读:
    矢量瓦片切割工具,注意不是切图工具哦
    openlayers模仿google地图--地图版权随鹰眼关闭打开而改变位置
    centos建立本地yum源shell脚本
    python通用序列操作
    awk手册
    linux启动级别简单说明
    win8程序开机自启动管理
    linux系统监控shell脚本
    shell脚本实现源码lamp自动化安装
    python实现冒泡排序
  • 原文地址:https://www.cnblogs.com/1208712478qq/p/14476854.html
Copyright © 2011-2022 走看看