zoukankan      html  css  js  c++  java
  • HDU 4669 Mutiples on a circle (2013多校7 1004题)

    Mutiples on a circle

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
    Total Submission(s): 171    Accepted Submission(s): 28


    Problem Description
    Tom has a necklace with n jewels. There is a number on each jewel. Now Tom wants to select a wonderful chain from the necklace. A chain will be regarded wonderful if the wonderful value of the chain is a multiple of a key number K. Tom gets the wonderful value using this way:He writes down the number on the chain in clockwise order and concatenates them together. In this way, he gets a decimal number which is defined as the wonderful value.
    For example, consider a necklace with 5 jewels and corresponding numbers on the jewels are 9 6 4 2 8 (9 and 8 are in neighborhood). Assume we take K=7, then we can find that only five chains can be multiples of K. They are 42, 28, 896, 42896 and 89642.

    Now Tom wants to know that how many ways he can follow to select a wonderful chain from his necklace.
     
    Input
    The input contains several test cases, terminated by EOF.
    Each case begins with two integers n( 1 ≤ n ≤ 50000), K(1 ≤ K ≤ 200),the length of the necklace and the key number.
    The second line consists of n integer numbers, the i-th number ai(1 ≤ ai ≤ 1000) indicating the number on the ith jewel. It’s given in clockwise order.
     
    Output
    For each test case, print a number indicating how many ways Tom can follow to select a wonderful chain.
     
    Sample Input
    5 7 9 6 4 2 8
     
    Sample Output
    5
     
    Source
     
    Recommend
    zhuyuanchen520
     

    看了题解发现,题解的做法比我简单多了。

    我是先统计没有形成环的,就是a[n]和a[1]没有连在一起的,这样O(nk)就可以统计完。

    然后是统计a[n]和a[1]相连的。

    只要把前缀接到后缀的后面的,然后取模统计。

      1 /* **********************************************
      2 Author      : kuangbin
      3 Created Time: 2013/8/13 15:10:49
      4 File Name   : F:2013ACM练习2013多校71004.cpp
      5 *********************************************** */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 
     19 
     20 using namespace std;
     21 
     22 const int MAXN = 50010;
     23 int a[MAXN]; //第i个数
     24 int end[MAXN];//end[i]表示第i个数...一直连接到第n个数对k取模后的值
     25 
     26 int len[MAXN];//第i个数的长度
     27 
     28 int b[2][220]; //滚动数组,预处理以第i个数结尾的,所有连接成的对k取模得到值的个数
     29 
     30 int getlen(int n)//得到n有多少位
     31 {
     32     int ret = 0;
     33     while(n)
     34     {
     35         ret++;
     36         n/=10;
     37     }
     38     return ret;
     39 }
     40 int Ten[10];//10^i  预处理,本来预处理了很大10^i的,结果发现一预处理这个就超时,T_T
     41 
     42 
     43 
     44 int main()
     45 {
     46     //freopen("in.txt","r",stdin);
     47     //freopen("out.txt","w",stdout);
     48     int n,k;
     49     while(scanf("%d%d",&n,&k) == 2)
     50     {
     51         for(int i = 1;i <= n;i++)
     52         {
     53             scanf("%d",&a[i]);
     54             len[i] = getlen(a[i]);
     55         }
     56         Ten[0] = 1;
     57         for(int i = 1;i < 5;i++)
     58             Ten[i] = Ten[i-1]*10%k;
     59         int now = 0;
     60         memset(b,0,sizeof(b));
     61         b[now][a[1]%k] = 1;
     62         long long ans = 0;
     63         ans += b[now][0];
     64         for(int i = 2;i <= n;i++)
     65         {
     66             memset(b[now^1],0,sizeof(b[now^1]));
     67             b[now^1][a[i]%k] = 1;
     68             for(int j = 0;j < k;j++)
     69             {
     70                 if(b[now][j] == 0)continue;
     71                 int ttt = j*Ten[len[i]]%k+a[i];
     72                 ttt%=k;
     73                 b[now^1][ttt] += b[now][j];
     74             }
     75             now^=1;
     76             ans += b[now][0];
     77 
     78         }
     79         //前面累加的结果是没有a[n]和a[1]连接的。
     80         //后面的是a[n]和a[1]连接的计数
     81         end[n] = a[n]%k;
     82         int tmp = len[n];
     83         int SSSS = Ten[len[n]];
     84         for(int i = n-1;i>= 1;i--)
     85         {
     86             end[i] = a[i]*SSSS%k + end[i+1];
     87             end[i]%=k;
     88             tmp += len[i];
     89             SSSS = SSSS*Ten[len[i]]%k;
     90         }
     91         tmp = len[1];
     92         SSSS = Ten[len[1]];
     93         int tt = a[1]%k;
     94         for(int i = 1;i < n;i++)
     95         {
     96             b[now][end[i]]--;
     97             for(int j = 0;j < k;j++)
     98             {
     99                 int ppp = (j*SSSS%k+tt)%k;
    100                 if(ppp == 0)ans += b[now][j];
    101             }
    102             tt = tt*Ten[len[i+1]]+a[i+1];
    103             tt%=k;
    104             tmp+=len[i+1];
    105             SSSS = SSSS*Ten[len[i+1]]%k;
    106         }
    107         printf("%I64d
    ",ans);//T_T 一定要long long,这题貌似是刚好超int~~
    108 
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    基础 之 数组
    记录某个进程任意的采集时间内,top 10 的cpu和内存值的平均和求和
    8、广度优先搜索
    7、散列表
    计算机网络之从接入网到互联网
    计算机网络
    15、python之导入模块
    14、函数之匿名函数(lambda)
    13、python中的函数(闭包与装饰器)
    6、快速排序
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3255856.html
Copyright © 2011-2022 走看看