zoukankan      html  css  js  c++  java
  • 1282 时钟(最小表示法+hash)

    题目来源: Codility
    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
    有N个时钟,每个时钟有M个指针,P个刻度。时钟是圆形的,P个刻度均分整个圆。每个时钟每个指针指向整数刻度,并且每个时钟自身指针指向的数字都不同。你可以任意旋转时钟的表盘,但是你不能转指针。问最后有多少对时钟可以变成相同的状态。
     
    例如:N = 5,M = 2,P = 4,5个时钟的数据如下{1, 2} {2, 4} {4, 3} {2, 3} {1, 3}
     
     
    经过旋转后。 其中(1, 3), (1, 4), (2, 5) 和 (3, 4)是相同的。
     
     
    给出所有时钟的数据,求有多少对时钟是相同的。
    Input
    第1行:3个数N, M, P中间用空格分隔,其中N为时钟的数量,M为表针的数量,P为刻度的数量(1 <= M, N <= 500, 1 <= P <= 10^9, M <= P)。
    第2 - N + 1行:每行M个数,对应一个时钟,M个指针的位置。
    Output
    输出有多少对时钟是相同的。
    Input示例
    5 2 4
    1 2
    2 4
    4 3
    2 3
    1 3
    
    Output示例
    4



    //思路是有的,但是最小表示法不知道,一只wa。。。学习了最小表示法,还是很好理解的
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define INF 0x3f3f3f3f
     4 #define LL long long
     5 #define MX 505
     6 
     7 const int hash_ = 133331;
     8 
     9 int n, m, p;
    10 int ans;
    11 int ke[MX];
    12 int cha[MX];
    13 map<LL,int> zz;
    14 
    15 int get_min(int *s, int len) //返回最小表示法的始端
    16 {
    17     int i = 0, j = 1, k = 0;
    18     while(i<len && j<len && k<len)
    19     {
    20         int t = s[(i+k)%len]-s[(j+k)%len];
    21         if (!t) k++;
    22         else
    23         {
    24             if (t>0) i += k+1;
    25             else j += k+1;
    26             if (i==j) j++;
    27             k = 0;
    28         }
    29     }
    30     return i<j?i:j;
    31 }
    32 
    33 void calc()
    34 {
    35     sort(ke,ke+m);
    36     for (int i=1;i<m;i++)
    37         cha[i-1] = ke[i]-ke[i-1];
    38     cha[m-1] = ke[0]+p-ke[m-1];
    39     int dex= get_min(cha,m);
    40 
    41     LL has=0, quan =1;
    42     for (int i=0;i<m;i++)
    43     {
    44         has += cha[(dex+i)%m]*quan;
    45         quan*= hash_;
    46     }
    47     ans+=zz[has];
    48     zz[has]++;
    49 }
    50 
    51 int main()
    52 {
    53     scanf("%d%d%d",&n,&m,&p);
    54     ans = 0;
    55     for (int i=0;i<n;i++)
    56     {
    57         for (int j=0;j<m;j++)
    58             scanf("%d",&ke[j]);
    59         calc();
    60     }
    61     printf("%d
    ",ans);
    62     return 0;
    63 }
    View Code


  • 相关阅读:
    省选模拟24 题解
    省选模拟23 题解
    省选模拟22 题解
    省选模拟21 题解
    省选模拟20 题解
    省选模拟19 题解
    省选模拟18 题解
    源码分析工具
    深入理解js的变量提升和函数提升
    python并发编程之IO模型
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7608830.html
Copyright © 2011-2022 走看看