B. Carries
Time Limit: 1000ms
Memory Limit: 65536KB
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
题目链接:http://www.bnuoj.com/v3/contest_show.php?cid=6865#problem/B
题目大意:h(a, b)表示计算a+b时进位的次数,要求题目给的那个公式的答案
题目分析:可以把每个数位分开讨论,比如现在求个位的时候,把每个数字对10取余的得到b数组再排序,然后对于b[i]我要找数组中大于等于10-b[i]的数字的个数,就是个位进十位的次数,这里找的时候直接二分,十位进百位,百位进千位也是同样的方法,n的范围是1e5,数字最多10位,所以总的复杂度位10n*log(n)
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 1e5 + 5;
int a[MAX], b[MAX];
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
int ten = 1;
ll ans = 0;
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= 9; i++)
{
ten *= 10;
for(int j = 0; j < n; j++)
b[j] = a[j] % ten;
sort(b, b + n);
for(int j = 0; j < n; j++)
ans += (ll) ((b + n) - lower_bound(b + j + 1, b + n, ten - b[j]));
}
printf("%lld\n", ans);
}
}