SCU 4437Carries(数论)

来源:互联网 发布:js判断浏览器语言 编辑:程序博客网 时间:2024/04/29 19:14

Carries

frog has (n) integers (a_1, a_2, \dots, a_n), and she wants to add them pairwise.

Unfortunately, frog is somehow afraid of carries (进位). She defines hardness (h(x, y)) for adding (x) and (y) the number of carries involved in the calculation. For example, (h(1, 9) = 1, h(1, 99) = 2).

Find the total hardness adding (n) integers pairwise. In another word, find [\sum_{1 \leq i < j \leq n} h(a_i, a_j)].

Input

The input consists of multiple tests. For each test:

The first line contains (1) integer (n) ((2 \leq n \leq 10^5)). The second line contains (n) integers (a_1, a_2, \dots, a_n). ((0 \leq a_i \leq 10^9)).

Output

For each test, write (1) integer which denotes the total hardness.

Sample Input

25 5100 1 2 3 4 5 6 7 8 9

Sample Output

120

题意:就是这个青蛙讨厌进位,问这些任意两个相加会产生多少次进位
思路:看题就想到暴力的一定有很多人,但再一看数据范围就傻眼了吧,就算优化一下知道用mod的也不一定能过,详细的解释全在代码注释里面的
完整代码如下:

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<stdlib.h>#define MAX 100010using namespace std;int main(void){    int n;    while(cin >>n)    {        int a[MAX],b[MAX];        int i,j,k;        for(i=1;i<=n;i++)        {            cin >> a[i];        }        long long int sum = 0;        for(k=1;k<=9;k++)         {            int mod = pow(10,k);//分别对10,100,1000 ...... 1e9 取余             for(i=1;i<=n;i++)                b[i] = a[i] % mod;            sort(b+1,b+1+n);//把取余后的结果进行排序,再利用二分.              /*如果取余后的结果俩个数相加和大于mod则会在这个位次产生一次进位*/            j = 1;//利用二分查找             for(i=n;i>j;i--)//这个从末尾最大的开始             {                while(j<i)//这个从头开始,这里的j不用初始化,应为如果后面最大的加上j前面的都不行那么在i前面的更小的也不行                 {                    int num = b[i] + b[j];                    if(num >= mod)//如果首尾相加比模大的话就跳出                         break;                    j++;                }                /*例如样例2对10取余后为0,1,2,3......,7,8,9;0和9相加不符合,1和9相加符合则跳出,因为1符合                所以1后面的知道9的下标位置这些数和9相加都能产生进位。同样这里的j也不用初始化,因为最大的数9与j前面的都没                产生进位,那么9前面的数也不会产生进位。注意思考*/                sum += (i-j);//加上产生进位的次数             }        }        cout << sum << endl;    }    return 0;}

顺便吐槽下,智商的差距真是无法逾越啊,搞ACM真是伤不起啊。

0 0
原创粉丝点击