数学问题

一、%运算符的使用

避免出现负余数:采用将余数加上出书再对除数求一次余即可。

 r' = (r+b)%b;

在大数求模中,为了避免溢出:

 (a*b)%c = (a%c * b%c)%c
 (a+b)%c = (a%c + b%c)%c

例一: 还是A+B
在求A+B之前要判断一下,A和B的后K位数字是否相等,相等的话,输出-1

#include <stdio.h>

int main () {
    //k位数字相同的话,直接输出-1
    int A,B,K;
    while(scanf("%d%d%d",&A,&B,&K)!=EOF)
    {
        if(A==0 && B==0) break;
        int ans = -1;
        //判断后k位是否相等
        while(k--)
        {
          int p1 = A%10;
          A/=10;
          int p2 = B%10;
          B/=10;
          if(p1 != p2)
          {
            ans = A+B;
            break;
          }
        }
        printf("%d\n",ans);
    }
    return 0;
}

例二: 守形数
守形数是这样一种整数,它的平方的低位部分等于它本身。
比如25的平方是625,低位部分是25,因此25是一个守形数。
编一个程序,判断N是否为守形数。
解题思路:
唯一的难点在于,不好判断低位部分是几位。第一感觉是计算出n有几位,然后看ns的后几位即可,但是感觉这么着和两个数同时/10看余 复杂度一样的。就采用了不断/10和比较余数的方案。

当n等于0的时候,说明把n的所有位数都参与了比较仍然没有找到不同的数字,这是即可跳出循环,判断为yes。如果在循环中有1位的不同,即可输出no.

#include <stdio.h>

int main () {
    //比较n*n 和 n的多少位的位数是否相同
    int n;
    while(scanf("%d",&n)!=EOF)
    {
      int N = n*n;
      while(n!=0)
      {
         int num1 = n%10;
         n /=10;
         int num2 = N%10;
         N/=10;
         if(num1 !=num2)
         {
           printf("No!\n");
         }
      }
      printf("Yes!\n");
    }
    return 0;
}

二、数位拆解
特殊乘法:
123 *45 = 1*4 +1*5 +2*4+2*5+3*4+3*5
输入两个小于 1000000000
将拆解好的数字放到两个数组中,然后逐位进行相乘

#include <stdio.h>

int main () {
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
      int buf1[20],buf2[20],size1=0,size2=0;
      //数位拆解
      while(a!=0)
      {
        buf1[size1++] = a%10;
        a /=10;
      }
      while(b!=0)
      {
        buf2[size2++] = b%10;
        b/=10;
      }

      int ans = 0;
      //这里注意数组越界
      int i,j=0;
      for(i=0;i<size1;i++)
      {
        for(j=0;j<size2;j++)
        {
          ans +=buf1[i]*buf2[j];
        }
      }
      printf("%d\n",ans);
    }
    return 0;
}

另外一种解法: 直接将读入数字当成字符串进行处理 代码更加简洁

#include <stdio.h>

int main () {
    char a[11],b[11];
    while(scanf("%s%s",a,b)!=EOF)
    {
        int ans = 0;
        int i,j=0;
        for(i=0;a[i]!=0;i++)
         for(j=0;b[j]!=0;j++)
            ans +=(a[i]-'0')*(b[j]-'0');
        printf("%d\n",ans);
    }
    return 0;
}

例题一
设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321)
求N的值
输入:
程序无任何输入数据
输出:
输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开
核心思想:
一个数逆序 :

s*10 + n%10;
n / =10;
#include <stdio.h>
int reverse(int n)
{
    int s = 0;
    while(n!=0)
    {
      s = s*10 + n%10;
        n/=10;
    }
    return s;
}
int main () {
    //没有任何的输入数据,直接输出满足条件的数据
    //将一个数组反序
    int i=1000;
    for(i=1000;i<10000;i++)
    {
      if(i*9 == reverse(i))
        printf("%d\n",i);
    }
    return 0;
}

例题二:
对称平方数
打印所有不超过n(n<256)的,其平方具有对称性质的数。

如11*11=121

输入:
无任何输入数据
输出:
输出具有题目要求的性质的数。如果输出数据不止一组,各组数据之间以回车隔开。

#include <stdio.h>
int isreverse(int n)
{
  //将数字拆解为字符串,然后遍历
  char a[5];
  int i = 0;
  while(n!=0)
  {
    a[i++] = n%10;
    n /=10;
  }
  i--;
  int j;
  for(j=0;j<i;j++)
  {
    if(a[j]!=a[i])
      return 0;
    else
      i--;
  }
    return 1;
}

int main () {
    //打印在 256之前 平方具有对称性的数字
    int i;
    for(i=0;i<256;i++)
    {
      if(isreverse(i*i))
          printf("%d\n",i);
    }
    return 0;
}

例题三:
Digital Roots
样例输入:
24
39
0
样例输出:
6
3
代码:

#include<stdio.h>
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        int ans = n;
        while(ans/10 !=0)
        {
           int a = ans%10;
           ans /=10;
           int b = ans%10;
           ans = a+b;
        }
        printf("%d\n",ans);

    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值