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的主要内容,如果未能解决你的问题,请参考以下文章

scu 4437 Carries

scu4437(二分)

[HDOJ4588]Count The Carries(数学,规律)

HDU 4588 Count The Carries 数位DP || 打表找规律

Dcm4che CFind SCU源代码分析

Dcm4che CFind SCU源代码分析