Carries
frog has n n integers a 1 ,a 2 ,…,a n a1,a2,…,an, and she wants to add them pairwise.
Unfortunately, frog is somehow afraid of carries (进位). She defines hardnessh(x,y) h(x,y) for adding x x and y y the number of carries involved in the calculation. For example, h(1,9)=1,h(1,99)=2 h(1,9)=1,h(1,99)=2.
Find the total hardness adding n n integers pairwise. In another word, find
Input
The input consists of multiple tests. For each test:
The first line contains 1 1 integer n n (2≤n≤10 5 2≤n≤105). The second line contains n n integers a 1 ,a 2 ,…,a n a1,a2,…,an. (0≤a i ≤10 9 0≤ai≤109).
Output
For each test, write 1 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个数,定义h(x,y)是x+y的进位次数,例如h(1,99)=2,因为1+99进了2位,要求求出所有的数相互组合相加进位次数的总和
题解:把每个数字对10,100,...1e9取模,分别把相应取模后的数字存到集合中,在每个集合中,先排序,再枚举第1~n个数,对于每个
数,找到与它相加大于模的那些数,统计这些数的个数全部加起来就是答案
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
#include<set>
#include<functional>
#include<iostream>
#include<math.h>
#include<vector>
#include<stdlib.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 5;
LL a[maxn],mod[15];
int main(){
int n;
mod[0]=1;
// freopen("in.txt","r",stdin);
for(int i=1;i<10;i++) mod[i]=mod[i-1]*10;
while(~scanf("%d",&n)){
vector<int>v[10];
for(int i=0;i<n;i++) {
scanf("%lld",&a[i]);
for(int j=1;j<10;j++) //对10^j取模
if(a[i]%mod[j]>0) v[j].push_back(a[i]%mod[j]);//存入相应的集合
}
LL ans=0;
for(int i=1;i<10;i++) {
sort(v[i].begin(),v[i].end());//从小打到排序,方便二分查找
for(int j=0;j+1<v[i].size();j++){ //二分查找x+v[i][j]>mod[i]的x的个数
ans+=v[i].size()-(lower_bound(v[i].begin()+j+1,v[i].end(),mod[i]-v[i][j])-v[i].begin());
}
}
printf("%lld\n",ans);
}
return 0;
}