C. Book Reading 求在[1,n]中的数中,能整除m的数 的个位的和

C. Book Reading

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Polycarp is reading a book consisting of nn pages numbered from 11 to nn. Every time he finishes the page with the number divisible by mm, he writes down the last digit of this page number. For example, if n=15n=15 and m=5m=5, pages divisible by mm are 5,10,155,10,15. Their last digits are 5,0,55,0,5 correspondingly, their sum is 1010.

Your task is to calculate the sum of all digits Polycarp has written down.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤10001≤q≤1000) — the number of queries.

The following qq lines contain queries, one per line. Each query is given as two integers nn and mm (1≤n,m≤10161≤n,m≤1016) — the number of pages in the book and required divisor, respectively.

Output

For each query print the answer for it — the sum of digits written down by Polycarp.

Example

input

Copy

7
1 1
10 1
100 3
1024 14
998244353 1337
123 144
1234312817382646 13

output

Copy

1
45
153
294
3359835
0
427262129093995

题意:输入n,m; 求在[1,n]中的数中,能整除m的数 的个位的和

题解:规律+模拟

例如:n=100    m=3

1-n能被3整除的有:3 6 9 12 15 18 21 24 27 30 33 36 ……99

余数分别为:      3 6 9 2 5 8 1 4 7 0 3 6 …… 9

发现循环节的个数有:10个数   且和为3 + 6+9+2+5+8+1+4+7+0 = 45

所以最后的结果为:(n/m/循环节的个数) *   一个循环的和 +  不够一个循环节的和
#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
int vis[10][12]={   //vis[i][0]  指m的个位数为i的时候循环节长度为vis[i][0],vis[i][j] (j>=1)是循环内的每一个数
    {1,0},
    {10,1,2,3,4,5,6,7,8,9,0},
    {5,2,4,6,8,0},
    {10,3,6,9,2,5,8,1,4,7,0},
    {5,4,8,2,6,0},
    {2,5,0},
    {5,6,2,8,4,0},
    {10,7,4,1,8,5,2,9,6,3,0},
    {5,8,6,4,2,0},
    {10,9,8,7,6,5,4,3,2,1,0}
};
int sum[10];
int main()
{
    ll t, n, m, ans;
    cin >> t;
    for(int i=0;i<10;i++)
    {
        for(int j=1;j<12;j++)
            sum[i]=sum[i]+vis[i][j];
    }

    while (t--)
    {
        ans = 0;
        cin >> n >> m;
        ll k=n/m;
        ll x=m%10;
        ans=ans+sum[x]*(k/vis[x][0]);
        k=k%vis[x][0];
        for(int i=1;i<=k;i++)//不够一个循环的和
            ans=ans+vis[x][i];
        cout<<ans<<endl;
    }
    return 0;
}


原文地址:https://www.cnblogs.com/-citywall123/p/11599335.html

时间: 2024-10-12 08:16:36

C. Book Reading 求在[1,n]中的数中,能整除m的数 的个位的和的相关文章

求二维数组中子数组和中最大的值,及子数组

求二维数组中子数组和中最大的值,及子数组 个人信息:就读于燕大本科软件工程专业 目前大三; 本人博客:google搜索"cqs_2012"即可; 个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献; 编程语言:C++ ; 编程坏境:Windows 7 专业版 x64; 编程工具:vs2008; 制图工具:office 2010 powerpoint; 硬件信息:7G-3 笔记本; 真言 每次着急写程序,碰到问题就头疼,头疼之后便是满满的收获,付出总有回报. 题目 求

hdu3065 病毒侵袭持续中 AC自动机入门题 N(N &lt;= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。

/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数. 思路:ac自动机做发,val标记每一个病毒串编号,通过print函数统计每一个病毒出现的次数. AC自动机好文章:http://www.cppblog.com/menjitianya/archi

【C语言】输入一组整数,求出这组数字子序列和中最大值

//输入一组整数.求出这组数字子序列和中最大值 #include <stdio.h> int MAxSum(int arr[],int len) { int maxsum = 0; int i; int j; for (i = 0; i < len; i++) { int thissum = 0; for (j = i; j < len; j++) { thissum += arr[j]; if (thissum>maxsum) maxsum = thissum; } } r

(c语法百题4)求两数中的较大者

知识点: if语句 内容: 求两数中的较大者 输入说明: 一行两个数 输出说明: 一行 一个 数字 输入样例: 若题目没有特别说明,则应该以多组测试数据方式读取,或者参考a001. 3 5 输出样例 : 5 #include <stdio.h> int main() { int a,b,c; scanf("%d %d",&a,&b); if(a<b) { c=b; a=c; } printf("%d\n",a); return 0;

求一个序列中两个只出现一次的数

当然了,O(1)空间复杂度是必须的... 先看一个简单版: 求出一个序列中一个只出现一次的数 COJ 1217 奇数个的那个数 http://122.207.68.93/OnlineJudge/problem.php?id=1217 我们知道任意两个相同的数 异或结果为0  任何数与0异或结果是其本身  异或运算满足交换律 亦即:a^a=0     a^0=a      (a^b)^(a^b)=(a^a)^(b^b)=0^0=0 这样我们就得到了一个用异或运算的解法 1 #include<std

算法题:给你一个自然数N,求[6, N]之内的全部素数中, 两两之和为偶数的那些偶数。

/* 算法题:给你一个自然数N,求[6, N]之内的全部素数中. 两两之和为偶数的那些偶数. */ #include <iostream> using namespace std; void Grial(int n) { int *b = new int[n]; int k = 0; b[k++] = 2; b[k++] = 3; b[k++] = 5; for (int i = 6; i < n; i++) { int j; for (j = 0; j < (k+1) / 2 ;

二叉树知道前序中序或者中序后序求另外一个排列

二叉树的遍历: 前序遍历:根节点->左子树->右子树 中序遍历:左子树->根节点->右子树 后序遍历:左子树->右子树->根节点 求下面树的三种遍历: 前序遍历:abdefgc 中序遍历:debgfac 后序遍历:edgfbca 详细的二叉树的操作可以看一下我之前写的文章 二叉树java 已知前序.中序遍历,求后序遍历 前序遍历的第一个值就是根节点,然后再中序遍历中找到这个值,那么这个值的左边部分即为当前二叉树的左子树部分前序遍历结果,这个值的右边部分即为当前二叉树的右

Jsの数组练习-求一组数中的最大值和最小值,以及所在位置

要求:求一组数中的最大值和最小值,以及所在位置 代码实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv=&

Frogger POJ - 2253(求两个石头之间”所有通路中最长边中“的最小边)

题意 ? 题目主要说的是,有两只青蛙,在两个石头上,他们之间也有一些石头,一只青蛙要想到达另一只青蛙所在地方,必须跳在石头上.题目中给出了两只青蛙的初始位置,以及剩余石头的位置,问一只青蛙到达另一只青蛙所在地的所有路径中的"the frog distance"中的最小值. ? 解释一下"the frog distance": 题目中给出了一段解释"The frog distance (humans also call it minimax distance