[SCU4437] Carries [2015 Sichuan Province Contest Final B]

题意

就是现在给出 10 万个 109 以内的非负整数, 问他们两两相加一共会有多少次进位( 10 进制加法), 例如 99+1 2 次进位,10+19没有进位。

题解

这个题考虑进位的位置即可, 首先枚举进位是因为达到了 10,100,1000,,109 对于每一次枚举 10t , 就是在 10 万个数中对于每一个数 xmod10t , 所有的数模 10t 之后, 二分以下不小于 10tx 的数有多少个即可。可以用sort+upper_bound。

代码

/****************************************\
* Author : ztx
* Title  : B - Carries
* ALG    :
* CMT    : g++  I64d
* Time   :
\****************************************/

#include <cstdio>
#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define rep(i,l,r) for(i=(l);i< (r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
#define rev(i,r,l) for(i=(r);i> (l);i--)
typedef long long ll ;
typedef double lf ;
int CH , NEG ;
template <typename TP>inline void read(TP& ret) {
    ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;
    if (CH == '-') NEG = true , CH = getchar() ;
    while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;
    if (NEG) ret = -ret ;
}
template <typename TP>inline void readc(TP& ret) {
    while (ret=getchar() , ret<'!') ;
    while (CH=getchar() , CH>'!') ;
}
template <typename TP>inline void reads(TP *ret) {
    ret[0]=0;while (CH=getchar() , CH<'!') ;
    while (ret[++ret[0]]=CH,CH=getchar(),CH>'!') ;
    ret[ret[0]+1]=0;
}

#include <algorithm>

#define  maxn  100010LL
#define  infi  1100000000LL

int n ;
int point[20] ;
const int pow10[15] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000} ;// pow10[9]

int node_i ;
int cmp_i ;
struct node {
    int a[15] ;
    inline void in() {
        read(a[0]) ;
        Rep (node_i,1,9)
            a[node_i] = a[0]%pow10[node_i] ;
    }
    bool operator < (const node&b) const {
        return a[cmp_i] < b.a[cmp_i] ;
    }
} a[maxn] , tmp ;

int main() {
int i , j , ans ;
//    #define READ
    #ifdef  READ
        freopen(".in" ,"r",stdin ) ;
        freopen(".out","w",stdout) ;
    #endif
    while (scanf("%d", &n) != EOF) {
        Rep (i,1,n) a[i].in() ;
        ans = 0 ;
        Rep (i,1,9) {
            cmp_i = i ;
            std::sort(a+1,a+n+1) ;
            Rep (j,1,n) {
                tmp.a[i] = pow10[i]-a[j].a[i]-1 ;
                ans += n+1-(std::upper_bound(a+1,a+n+1,tmp)-a) ;
                if (tmp.a[i] < a[j].a[i]) ans -- ;
            }
        }
        printf("%d\n", ans/2) ;
    }
    #ifdef  READ
        fclose(stdin) ; fclose(stdout) ;
    #else
        getchar() ; getchar() ;
    #endif
    return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值