XMU 1608 nc与加法进位 【二分】

来源:互联网 发布:python量化交易文华 编辑:程序博客网 时间:2024/06/03 02:29

1608: nc与加法进位

Time Limit: 2000 MS  Memory Limit: 128 MB
Submit: 29  Solved: 27
[Submit][Status][Web Board]

Description

nc最近很无聊~所以他总是想各种有趣的问题来打发时间。
nc喜欢做加法运算,他对加法进位很感兴趣。现在给你n个数字,他想知道,这些数字两两相加,一共会出现多少次加法进位。

Input

第一行包含1个整数n,表示有n个数字。(n<=5000)
第二行包含n个数字,分别表示a1,a2,...an。(0 ≤ai ≤ 10^9).

Output

这些数字两两相加,出现加法进位次数。

Sample Input

3
43 58 85

Sample Output

5

HINT

Source

by cjf

[Submit][Status][Web Board]


题目链接:

  http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1608

题目大意:

  题目给出N个数,问这些数两两相加共会出现几次加法进位。

题目思路:

  【二分】

  N最大5000,其实这题直接拿高精度加法统计就能过,而且0ms,数据不算很强。

  NlogN的做法N可以达到10W。

  首先可以假设这N个数位数都相同(不足补0)

  枚举每一位(k=1~8),对于当前的这一位,将N个数按照当前这一位上数字从小到大排序。

  再枚举每个数,假设第i个数在第k位为x,则二分其余N-1个数这一位>=10-x的个数,加到答案上。

  (针对每一位去统计进位次数)

  这样时间复杂度降到NlogN。



/****************************************************         Author : Coolxxx    Copyright 2017 by Coolxxx. All rights reserved.    BLOG : http://blog.csdn.net/u010568270     ****************************************************/#include<bits/stdc++.h>#pragma comment(linker,"/STACK:1024000000,1024000000")#define abs(a) ((a)>0?(a):(-(a)))#define lowbit(a) (a&(-a))#define sqr(a) ((a)*(a))#define mem(a,b) memset(a,b,sizeof(a))const double EPS=1e-8;const int J=10;const int MOD=100000007;const int MAX=0x7f7f7f7f;const double PI=3.14159265358979323;const int N=5004;const int M=14;using namespace std;typedef long long LL;double anss;LL aans;int cas,cass;int n,m,lll,ans;int e[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};int a[N],b[N];int main(){    #ifndef ONLINE_JUDGE    freopen("1.txt","r",stdin);//  freopen("2.txt","w",stdout);    #endif    int i,j,k;    int x,y,z;//  for(scanf("%d",&cass);cass;cass--)//  for(scanf("%d",&cas),cass=1;cass<=cas;cass++)//  while(~scanf("%s",s))    while(~scanf("%d",&n))    {        for(i=1;i<=n;i++)            scanf("%d",&a[i]);        for(k=1;k<10;k++)        {            for(i=1;i<=n;i++)                b[i]=a[i]%e[k];            sort(b+1,b+1+n);            for(i=1;i<=n;i++)            {                int l,r,mid;                l=i+1,r=n;                while(l<=r)                {                    mid=(l+r+1)/2;                    if(b[mid]+b[i]<e[k])l=mid+1;                    else r=mid-1;                }                aans+=n-r;            }        }        printf("%lld\n",aans);    }    return 0;}/*// //*/


0 0
原创粉丝点击