zoukankan      html  css  js  c++  java
  • VJ的MNNUrank的E

    题意:

      给定数组A[] , 问两两数合并,有多少个合并数能被K整除。

    思路:

      情况① :  a与b都可以整除k,他们的两个合并数必定都可以整除k

        打个比方 a = 36 , b = 12 , k = 6 

        由于 (a % k == 0 && b % k == 0) , 可得 (a + b) % k == 0 且 (b + a) % k == 0 , 也就是3612 % 6 = 0 , 1236 % 6 = 0

      情况② :排除情况①的其余情况,根据余数进行判定

        首先,假设 a 和 b 进行合并 , a 有 n 位 ,b 有 m 位 :

        假如合并方法是 a + b :那么实际上拼凑成的数是 a  * 10 ^ m + b ,那么判断这个数是否整除k,也就是判断(a  * 10 ^ m + b) % k == 0 ,

        也就是判断(a  * 10 ^ m + b)% k + b % k == 0 ?

        由于情况①以及排除了 (a % k == 0 && b % k == 0) 的情况 , 所以只能当 (a  * 10 ^ m + b)% k + b % k = k 时,情况才成立。

        由于ai数据最大的是1e9 , n , m <= 9  , 所以我们可以直接计算出 (a * 10 ^ i)% k (i = 0 , 1 , 2 , 3 ....,9)的情况并记录下来.

        然后对于位数为m , 模k后的值为temp的数 ,他作为尾巴(后置位)的对答案的贡献是:

          个数 (位数为m,乘10 ^ 0 , 模k后的值为temp)  *  个数(位数为1 ~ 9 ,乘10 ^ m , 模k后的值为 k - temp)

        由此计算出所有的答案

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    const int maxn =  1e5 + 10;
    #define ios std::ios::sync_with_stdio(false)
    
    int a[maxn][10];///(b[i] * 10^j) % k
    int b[maxn];///存数组
    int num[maxn];///每个数有几位
    int ma[10][10][maxn];///位数为i ,乘的数为10^j的,余数为k的,个数
    signed main()
    {
        ios;cin.tie(0);
        int n , k;
        cin >> n >> k;
        for(int i = 1 ; i <= n ; i ++){
            cin >> b[i];
            a[i][0] = b[i] % k;
            for(int j = 1 ; j <= 9 ; j ++){ ///计算*1 *10 *100 ... 后的模数
                a[i][j] = a[i][j - 1] * 10;
                a[i][j] %= k;
            }
        }
        for(int i = 1 ; i <= n ; i ++){ ///计算位数
            int cnt = 0;
            int now = b[i];
            while(now){
                cnt ++ , now /= 10;
            }
            num[i] = cnt;
        }
    
        for(int i = 1 ; i <= n ; i ++){
            for(int j = 0 ; j <= 9 ; j ++){
                ma[num[i]][j][a[i][j]] ++;///每个数的位数,乘10 ^ j , 模值为a[i][j]
            }
        }
    
        int ans = 0;
        for(int i = 1 ; i < 10 ; i ++){
            for(int j = 0 ; j < 10 ; j ++){
                    for(int l = 1 ; l < k ; l ++) ans += ma[i][0][l] * ma[j][i][k - l];///情况2 ,(位数为i,模数为l的作为尾巴)(位数为j,乘10 ^ i,模数为k - l作为头)
            }
            if(ma[i][0][0] == 0)continue;
            int sum = 0;
            for(int l = 0 ; l < 10 ; l ++) sum += ma[l][i][0]; ///情况1
            ans += ma[i][0][0] * (sum - 1);///要排除掉自己和自己组合的那种
        }
        cout << ans << '
    ';
        return 0;
    }
    View Code

        

      

      

  • 相关阅读:
    Thread中带参方法无法使用之解决方案
    项目相关的风险要素及分类
    AspNetPager分页示例之DataGrid(PostBack分页)
    Substitution 类 (asp.net 2.0 )
    自定义HTTP处理程序显示图片(asp.net 2.0)
    常见文件扩展名和它们的说明
    基于.NET的开源GIS项目(转)
    项目开发流程标准
    AOP(Aspect Oriented Programming) 面向方面编程
    项目实施及管理标准
  • 原文地址:https://www.cnblogs.com/GoodVv/p/13726402.html
Copyright © 2011-2022 走看看