算法的基础数学问题

1、保留6位有效数字

保留第一个不为0的数,以及后面的5个数字。

首先通过计算可以得到小数之前后以多少为有效数字,在通过相应的设置,去保留有效数字。

2、p2181 对角线

典型的 找规律题(这个规律不好找呀)

n 交点 2 = 0 3 = 0 4 = 1 5 = 5 6 = 15 7 = 35 8 = 70
相邻两项做差,
a[3] - a[2] = 0, a[4] - a[3] = 1, a[5] - a[4] = 4, a[6] - a[5] = 10 ,a[7] - a[6] = 20, a[8] - a[7] = 35
      再次做差(一次找不出规律,再次做差,找不断找)
 1 3 6 10 15
      再次做差
 1 2 3 4 5 ……
 代码的实现方法,从最终的结果 1 2 3 4 5  一层一层往上推,用数组来实现代码

 for (int i = 1; i <= n; i++) //最终结果插值 1 2 3 4 5
 {
    a1[1] = a[i - 1] + i;  //网上推一层,1 3 6 10 15 ()数组存储这些结果,方便下一数组用
  }
for (int i = 1; i <= n; i++ ) //最终结果插值 1 2 3 4 5
{
    a2[i] = a2[i - 1] + a1[i];//往上推两层,利用 a1[i]算一层,a2[i]算是第二层
}
for (int i = 1; i <= n; i++)
{
    a3[i]= a3[i] - a2[i]; //同理
}
如果 n = 6
    1 2 3 4 5 6
    1 3 6 10 15 21  去一层
    1 4 10 20 35 56  去一层
    1 5 15 35 70 126  去一层
    最终结果为 a3[n - 3] = 15 便是最终结果

3、相遇问题、卧槽,我连相遇都不会了

两个火车相向而行,分别有自己的速度,和车长,从车头开始相遇,问何时,车尾相遇,

总相遇路程,为两车车长,总速度为两车的总速度合,时间用v - t 公式即可求。

4、关于输出小数时,应注意

当要把一个数输出,如 0.33333333……,时,光用 100/ 3是不行的,c语言会自动把他转化成 整数,而不是小数,所以应这样写。。 cout << 1.0 * 100/ 3.0;

5、1019 数字黑洞

解题思路:将输入的数字转换成数组进行保存,然后对数组进行升序排列,和降序排列,最大值等于升序排列的,最小值等于降序排列的,让后输出做出的差

当做出的最终的差值,等于6174时,或者等于0时,就结束了输入。

6、何为闰年

条件一:能被4整除,但不能被100整除

条件二:能被400整除

7、买铅笔

解题思路:让价格和数量不断通过i<<=1(i=i * 2)的方式来成倍的增加,直到数量大于或等于最大数量,然后,在进行微调,可能买的多了,减去一些,有可能减的太少了,在加上一些。(刚才的过程就是,大幅度的往上调,然后在进行一些微调),然后在通过一个最小值,来输出最小花费。

8、螺旋矩阵

解题思路:

分析:首先计算行数m和列数n的值,n从根号N的整数部分开始,往前推一直到1,找到第一个满足N % n== 0的,m的值等于N/n~将N个给定的值输入数组a,并将a数组中的值按非递增排序,接着建立m行n列的数组b,填充时按层数填充,一个包裹矩阵的口字型为一层,计算螺旋矩阵的层数level,如果m的值为偶数,层数为m/2,如果m为奇数,层数为m/2+1,所以level = m / 2 + m % 2;因为是从左上角第1个格子开始,按顺时针螺旋方向填充,所以外层for循环控制层数i从0到level,内层for循环按左上到右上、右上到右下、右下到左下、左下到左上的顺序一层层填充,注意内层for循环中还要控制t <= N – 1,因为如果螺旋矩阵中所有的元素已经都填充完毕,就不能再重复填充~填充完毕后,输出整个矩阵~

大致而言:

  1. 行和列先确定:列n确定方法:从根号N开始,往前找,直到找到第一个(N%n == 0)的值为止,从而确定行,用N / n;

  2. 建立m行n列的数组

  3. 往数里面填充数据,一层一曾填充,

  4. 层数确定方法(level)行m为偶数是,level等于m/2,当m为奇数时,level等于m/2+1.所以最终level等于 m/2 + m %2

  5. 开始填充数据

    int level = m / 2 + m % 2;
        for (int i = 0; i < level; i++) {
            for (int j = i; j <= n - 1 - i && t <= N - 1; j++)
                    b[i][j] = a[t++];
            for (int j = i + 1; j <= m - 2 - i && t <= N - 1; j++)
                    b[j][n - 1 - i] = a[t++];
            for (int j = n - i - 1; j >= i && t <= N - 1; j--)
                    b[m - 1 - i][j] = a[t++];
            for (int j = m - 2 - i; j >= i + 1 && t <= N - 1; j--)
                    b[j][i] = a[t++];
        }
    

9三角形的判断

不是三角形,就是两个小边,一定小于等于第三边即可

10、典型例题(审题问题)

这道题我审题有问题:首先x尽可能的大,k尽可能的小,说明,x从最大开始遍历,k从最小开始遍历,且,每周内固定筹集,要在52个星期内筹完,说明,一定是在52个星期去筹集钱,且刚好筹完。

11、一个集合中所有元素求和问题

研究 1 2 3 4
//子集[] [1] [2] [3] [4] [1 2] [1 3] [1 4] [2 3] [2 4] [3 4] [1 2 3] [1 2 4] [1 3 4] [2 3 4] [1 2 3 4]
//1*8+2*8+3*8+4*8=(1+2+3+4)*2^(4-1) 
//发现规律 输入元素和*2^(n-1) 

12、对于不该表原有的顺序与换位置

像这类问题而言:使得所有负值元素都排在非负值元素的前面,而 [0, K] 区间内的元素都排在大于 K 的元素前面。但每一类内部元素的顺序是不能改变的。

尽量使用二维数组,每个二维数组的一位数组里存放一类情况,在按照要求输出即可。

13、关于多少元素反转多少元素不反转问题

:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。

这种问题,用for循环解决。

for(int i = 0; i < sum - (sum % k); i+= k)
{
    
}

14、

问题描述:正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?

//答案8879
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int judge(int year)//判断是否为闰年(闰年2月份29天,平年28天)
{
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
    {
        return 1;
    }
    else {
        return 0;
    }
}

int main()
{
    int w = 6; //这一年是从星期六开始的
    int step = 0; //千米数
    int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//月份
    for (int year = 2000; year <= 2020; year++) //年份
    {
        for (int m = 1; m <= 12; m++) //月份
        {
            for (int d = 1; d <= month[m] + ((m == 2) ? judge(year) : 0); d++, w = w % 7 + 1) //天数和星期数的判断
            {
                step++;
                if (d == 1 || w == 1) step++;
                if (year == 2020 && d == 1 && m == 10) {
                    cout << step << endl;
                }
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值