BNUOJ-50393-Carries

B. Carries
Time Limit: 1000msMemory Limit: 65536KB 64-bit integer IO format: %lld Java class name: Main
Submit Status PID: 50393
frog has n integers a1,a2,…,an, and she wants to add them pairwise.

Unfortunately, frog is somehow afraid of carries (进位). She defines \emph{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
∑1≤i<j≤nh(ai,aj)
.
Input
The input consists of multiple tests. For each test:

The first line contains 1 integer n (2≤n≤105). The second line contains n integers a1,a2,…,an. (0≤ai≤109).
Output
For each test, write 1 integer which denotes the total hardness.
Sample Input
2
5 5
10
0 1 2 3 4 5 6 7 8 9
Sample Output
1
20

题意:多组输入,第一行n,下一行有n个数字,输出这n个数字两两组合产生的进位次数。

思路:一位数加上一位数的结果是两位数,那这次运算一定产生了进位。同理,两位数加上两位数的结果是三位数,那这次运算一定也产生了进位。
公式归纳:如果num1%temp*10+num2%temp*10>=temp*10则产生了进位

代码

#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=100005;
int num1[maxn];
int num2[maxn];
int main()
{
    int N;
    while(~scanf("%d",&N))
    {
        for(int i=0; i<N; i++)
            scanf("%d",&num1[i]);
        int temp=1;//进制
        long long int sum=0;//记录进位总数
        for(int i=0; i<9; i++)//九位数
        {
            temp=temp*10;
            for(int j=0; j<N; j++)
                num2[j]=num1[j]%temp;
            sort(num2,num2+N);//升序排列
            int flag=N;//临时记录N
            for(int j=0; j<N; j++)
            {
                while(flag&&num2[j]+num2[flag-1]>=temp)//找到进位的边界
                    flag--;
                flag<=j?sum+=(N-flag-1):sum+=(N-flag);
            }
        }
        printf("%lld\n",sum/2);
    }
    return 0;
}

对于排序过后的那部分,还可以用二分查找进一步优化到O(nlogn);

你可能感兴趣的:(数学)