ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

蓝桥杯练习-3.12

2021-03-13 17:01:06  阅读:249  来源: 互联网

标签:return int pow 3.12 练习 else 蓝桥 abs 数组


蓝桥杯练习-3.12

代码练习

• 高精度加法

资源限制

时间限制:1.0s 内存限制:512.0MB

问题描述

输入两个整数ab,输出这两个整数的和。ab都不超过100位。

算法描述

由于ab都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
  定义一个数组AA[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b
  计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
  最后将C输出即可。

输入格式

输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。

输出格式

输出一行,表示a + b的值。

样例输入

20100122201001221234567890
2010012220100122

样例输出

20100122203011233454668012

代码实现

#include <stdio.h>
#include<string.h>
int main()
{
    int i,alen,blen,n;
	char a[101], b[101], c[103];//对应存两个加数和 和的字符数组,因为数字太大了,只能换为字符存储
	memset(c,0,sizeof(c));//清零
    scanf("%s%s", a, b);
     alen = strlen(a);
     blen = strlen(b);
    if (alen >= blen)//得到较大的那个长度,当作循环条件
    {
        n = alen;
    }
    else n = blen;
    for (i = 0; i < n; i++)
    {
        if (i < alen)
            c[i] += a[alen-i-1] - '0';//因为是字符,所以需要减去字符0,得到的ASCII码就是对应的数,而且是从低位开始加起,所以数组从倒着的开始
        if (i < blen)
            c[i] += b[blen-i-1] - '0';
        if (c[i] >= 10)
        {
            c[i+1] = c[i] / 10;//如果加起来大于10,要向高位进位
            c[i] %= 10;//然后本位得到余下的
        }
    }
    if (c[n] != 0)
    {
        for (i = n; i >= 0; i--)//倒着输出便是和
        printf("%d", c[i]);
    }
    else
    {
        for (i = n - 1; i >= 0; i--)//倒着输出便是和
        printf("%d", c[i]);
    }
    return 0;
}

❕注意:C++中,全局阈只能声明、初始化变量; 不能用于赋值、运算、调用函数等!!!也要注意,当两数都是相同位数时,最后输出的时候就不是n位了,而是n+1位

• 阶乘运算

资源限制

时间限制:1.0s 内存限制:512.0MB

问题描述

输入一个正整数n,输出n!的值。
  其中n!=1 *2 * 3… * n。

算法描述

n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数aA[0]表示a的个位,A[1]表示a的十位,依次类推。
  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
  首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。

输入格式

输入包含一个正整数nn<=1000。

输出格式

输出n!的准确值。

思路

根据算法描述,我们构建一个足够大的数组来存放这个大数的每一位,然后,我们用一个for循环来循环我们要乘的数,因为数每一位(个位,十位,百位…)都要乘,所以要有第二个循环,来循环每一个数组元素,这里需要用到进位,我们在每一轮乘数的开始,把进位初始为0,数组当前开到的最大下标记为high = 0,我们每一组元素乘完i再加上低位的进位以后,只需%10保留个位填到当前数组下标即可,然后进位数/10,一直到数组最大下标,如果这个时候进位数还有,就说明要开数组了,因为总数的位数又增加了。

代码实现:

#include <iostream>
using namespace std;
const int N = 100000;
int a[N];
int n;
int main()
{
    cin >> n;
    a[0] = 1;
    int r;//r代表进位数
    int high = 0;//high表示现在数组开到第几位了,第一次为0
    for (int i = 2; i <= n; i++)//从2开始乘
    {
        r = 0;//每乘完一个数后,进位都初始化为0
        for (int j = 0; j <= high; j++)
        {
            int mul = a[j] * i + r;
            a[j] = mul % 10;//当前位数保留个位的
            r = mul / 10;//进位,这里不用担心进位是很大的数怎么办,因为我们只是先把数组填满,多出来的肯定位数已经大过了数组上界high,没有影响
        }
        while(r)//因为进位可能不是一个个位数,所以当当前可以开到的最大数组个数都被填满数字了以后,
                //进位仍然不为0,就继续开拓数组,把进位一个个往后面填上
        {
            a[++high] = r % 10;
            r /= 10;
        }
    }
    for (int i = high; i >= 0; i--)
    {
        cout << a[i];
    }
    return 0;
}

在这里插入图片描述

• G 螺旋折线(第九届蓝桥杯)

Description

如图p1.png所示的螺旋折线经过平面上所有整点恰好一次。

对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。

例如dis(0, 1)=3, dis(-2, -1)=9

给出整点坐标(X, Y),你能计算出dis(X, Y)吗?

Input

X和Y

对于40%的数据,-1000 <= X, Y <= 1000

对于70%的数据,-100000 <= X, Y <= 100000

对于100%的数据, -1000000000 <= X, Y <= 1000000000

Output

输出dis(X, Y)

思路

**在这里插入图片描述
**

先分别找出y>0黄点的坐标变化规律,再找出y<0黄点的坐标变化规律。

当x的绝对值大于y的绝对值时也就是dis点在竖着的折现上时,都要用x轴上方黄色的点来计算。

当x的绝对值小于y的绝对值时也就是dis点在横着的折现上时,用x轴下方黄色的点来计算。

当y等于0也就是dis点在x轴上时单独计算。

代码实现(不完全对):

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
long long dis(long long x, long long y)
{
    if(x == 0)
    {
        if (y > 0)  return pow((2 * y), 2) - y;
        else if (y < 0)  return pow((2 * y), 2) - y + 4 * y;
        else if (y == 0)  return 0;
    }
    else if (x > 0)
    {
        if (y == 0)
        {
            return pow((2 * x), 2) + x;
        }
        else if (y > 0)
        {
            if (y == x)  return pow((2 * x), 2);
            else if (y < x)  return pow((2 * x), 2) + x - y;
            else if (y > x)  return pow((2 * y), 2) - y + x;
        }
        else if (y < 0)
        {
            if (abs(y) == x)  return pow((2 * x), 2) + 2 * x;
            else if (abs(y) < x)  return pow((2 * x), 2) + 2 * x - (x + y);
            else if (abs(y) > x)  return pow((2 * y), 2) - y + 4 * y - x;
        }
    }
    else if (x < 0)
    {
        if (y == 0)
        {
            return pow((2 * x), 2) + 2 * x + x;
        }
        else if (y > 0)
        {
            if (y == abs(x))
            {
                return pow((2 * x), 2) + 2 * x;
            }
            if (y < abs(x))  return pow((2 * x), 2) + 2 * x + x + y;
            if (y > abs(x))  return pow((2 * y), 2) - y + x;
        }
        else if (y < 0)
        {
            if ((abs(x) - abs(y)) == 1)  return pow((2 * y), 2) + y - 4 * y - x;
            else if (abs(y) < abs(x))  return pow(2 * (x + 1), 2) - 5 * (x + 1) + 1 + y;
            else if (abs(y) >= abs(x))  return (4 * abs(y) + 3) * abs(y) + abs(x);
        }
    }
}
int main()
{
    long long x, y;
    scanf("%lld%lld",&x, &y);
    printf("%lld\n",dis(x, y));
    return 0;
}

❕注意:注意函数类型为long long,传入的参数类型也为long long

标签:return,int,pow,3.12,练习,else,蓝桥,abs,数组
来源: https://blog.csdn.net/qq_52633682/article/details/114752506

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有