scu 4437 Carries
Posted Omz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scu 4437 Carries相关的知识,希望对你有一定的参考价值。
题意:
给出一个数组,计算所有对于1 <= i < j <= n,ai + aj的进位次数的总和。
思路:
一开始其实是卡在了,i只能与i之后的数字相加 == 。
转换一下,i之前的数字一定会与i相加,i之后的数字也一定会与i相加,所以对于数组中的所有数字,两两之间一定会加一次。
有个很显然的结论,如果说两个数相加会对10^k产生进位的话,那么一定满足(a % (10 ^ k) + b % (10 ^ k)) >= 10 ^ k。
所以就可以针对每一位的进位进行计算。
从10枚举到10的9次方。
每次枚举把所有的数模10 ^ k,然后进行排序,对于当前的x,二分查找大于等于10 ^ k - x的位置,然后进行累加。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 const int N = 1e5 + 10; 6 int a[N]; 7 int b[N]; 8 int main() 9 { 10 int n; 11 while (scanf("%d",&n) != EOF) 12 { 13 for (int i = 0;i < n;i++) 14 { 15 scanf("%d",&a[i]); 16 } 17 long long ans = 0; 18 int bas = 10; 19 for (int i = 1;i <= 9;i++) 20 { 21 for (int j = 0;j < n;j++) b[j] = a[j] % bas; 22 sort(b,b+n); 23 for (int j = 0;j < n - 1;j++) 24 { 25 int tmp = bas - b[j]; 26 //printf("%d*\n",tmp); 27 int p = lower_bound(b+j+1,b+n,tmp) - b; 28 ans += (n - p); 29 } 30 bas *= 10; 31 } 32 printf("%lld\n",ans); 33 } 34 return 0; 35 }
以上是关于scu 4437 Carries的主要内容,如果未能解决你的问题,请参考以下文章
[HDOJ4588]Count The Carries(数学,规律)