蓝桥杯2020年第十一届省赛真题-整数拼接

题目:蓝桥杯2020年第十一届省赛真题-整数拼接 - C语言网 (dotcpp.com)

根据题意,计算两个整数拼在一起能被K整除的个数;

思路:通过二维数组 a[位数][余数],求出每个数作为左边的数%k 得到 的余数(0~k-1)的个数,接着在遍历每个数,通过每个数的位数,找到 加起来 正好 能整除k的数 的 个数

0.通过数组s将每个数字记录下来;

1. 数字位数是1~9位,设可能拼在右边的数的位数为 j 。

    因为每个数都可能做 左边的数 ,因此需要求 每个数 作为 左边的数 的时候被 k 取余的情况;

    设result=(long long) pow (10 , j) * s[ i ]% k;

    可以通过二维数组s[ j ][ result ]来记录,注意result范围为(0 ~ k-1)

2. 每个数都可以作为右边的数,设数位为w。

    当 (右边的数%k+左边的数*pow(10,w) )%k==0时,这个数便可以计入

    将这个公式变形一下,可得k-右边的数%k = pow(10,w)* 左边的数 %k

    设 flag = k - 右边的数 % k ;

    注意特判: 如果 flag ==k 时,flag == 0 。这样 k-右边的数%k 范围为(0~ k-1)

    通过ans=ans+a[ w ][ flag ] 计算总数;

    注意特判:如果 同一个数 作为 左边的数 + 作为 右边的数 可以整除K,那么ans--;

代码如下:

#include<bits/stdc++.h>
using namespace std;
long long a[11][100004];
long long s[100004];
int wei(long long n){
	int ans=0;
	while(n){
		ans++;
		n=n/10;
	}
	return ans;
}
signed main()
{
	int n,k;
	cin>>n>>k;
	for (int i=0;i<n;i++){
		cin>>s[i];
	}
	for(int j=1;j<10;j++){
		for(int i=0;i<n;i++){
			long long result=(long long)pow(10,j)*s[i]%k;
			a[j][result%k]++;//0~k-1	
		}
	}
	long long ans=0;
	for(int i=0;i<n;i++){
		long long w=wei(s[i]);
		int flag=k-s[i]%k;
		if(flag==k)flag=0;
		ans=ans+a[w][flag];
		if((s[i]*(long long)pow(10,w)%k+s[i]%k)%k==0)ans--;
	}
	cout<<ans;
	return 0;
}

 PS:左边的数 求 余数 时也可以通过( result -1 ) %k +1 来求余数,其范围是1~k。这样求右边的数的余数时就不需要特判了;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值