Revolving Digits

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 24215    Accepted Submission(s): 5268

Problem Description
One day Silence is interested in revolving the digits of a positive integer. In the revolving operation, he can put several last digits to the front of the integer. Of course, he can put all the digits to the front, so he will get the integer itself. For example, he can change 123 into 312, 231 and 123. Now he wanted to know how many different integers he can get that is less than the original integer, how many different integers he can get that is equal to the original integer and how many different integers he can get that is greater than the original integer. We will ensure that the original integer is positive and it has no leading zeros, but if we get an integer with some leading zeros by revolving the digits, we will regard the new integer as it has no leading zeros. For example, if the original integer is 104, we can get 410, 41 and 104.
 
Input
The first line of the input contains an integer T (1<=T<=50) which means the number of test cases. 
For each test cases, there is only one line that is the original integer N. we will ensure that N is an positive integer without leading zeros and N is less than 10^100000.
 
Output
For each test case, please output a line which is "Case X: L E G", X means the number of the test case. And L means the number of integers is less than N that we can get by revolving digits. E means the number of integers is equal to N. G means the number of integers is greater than N.
 
Sample Input
1
341
Sample Output
Case 1: 1 1 1
题意:将一个数的每一个后缀移到前面和剩下的数字组成新的数字,求这些数字中比原来数字大的,相等的,小的,且不能重复的个数.
思路:将原来的串复制到原窜的后面,那么这样就可以得到,将后缀移到前面的相同的字串,其实就相当于将后缀串移到前面。那后一般的思想是,暴力比较。
假设原串的长度为l,那么新串就为2*l;拿原串与新串[1,l]比较。这样可以用EXKMP来优化,如果在这个点处,extend[i]>=l,那么这个点处往后再数l-1个点时,这个数就和
原数相等,否则小于的话就比较tt[i+extend[i]]-'0'>cc[extend[i]+1]-'0'的大小就好了。最后去重的话,用KMP的next数组,求下循环节,再每个数除循环节就可以了。
还有一种去重复的就是,最后相等的答案肯定是1,所以要除的那个数就是相等的个数;
  1. 1 #include<stdio.h>
  2. 2 #include<algorithm>
  3. 3 #include<iostream>
  4. 4 #include<string.h>
  5. 5 #include<stdlib.h>
  6. 6 #include<math.h>
  7. 7 #include<cstdio>
  8. 8 #include<queue>
  9. 9 #include<stack>
  10. 10 #include<map>
  11. 11 char tt[2*100005];
  12. 12 int extend[2*100005];
  13. 13 int nex[100005];
  14. 14 char d[100005];
  15. 15 char cc[100005];
  16. 16 int pp[100005];
  17. 17 void next1(int k);
  18. 18 void EXkmp(int k,int r);
  19. 19 using namespace std;
  20. 20 int main(void)
  21. 21 {
  22. 22 int i,j,k,p,q;
  23. 23 scanf("%d",&k);
  24. 24 for(int s =1; s<=k; s++)
  25. 25 {
  26. 26 memset(nex,0,sizeof(nex));
  27. 27 memset(extend,0,sizeof(extend));
  28. 28 scanf("%s",d);
  29. 29 int l=strlen(d);
  30. 30 for(i=1; i<=2*l; i++)
  31. 31 {
  32. 32 if(i<=l)
  33. 33 tt[i]=d[i-1];
  34. 34 else
  35. 35 tt[i]=d[i-l-1];
  36. 36 }
  37. 37 for(i=0; i<l; i++)
  38. 38 cc[i+1]=d[i];
  39. 39 j=0;
  40. 40 pp[0]=0;
  41. 41 pp[1]=0;
  42. 42 for(i=2; i<=l; i++)
  43. 43 {
  44. 44 while(j>0&&cc[j+1]!=cc[i])
  45. 45 {
  46. 46 j=pp[j];
  47. 47 }
  48. 48 if(cc[j+1]==cc[i])
  49. 49 {
  50. 50 j++;
  51. 51 }
  52. 52 pp[i]=j;
  53. 53 }
  54. 54 int temp=l/(l-pp[l]);
  55. 55 if(l%(l-pp[l])!=0)
  56. 56 {
  57. 57 temp=1;
  58. 58 }
  59. 59 next1(l);
  60. 60 EXkmp(2*l,l);
  61. 61 int a[4];
  62. 62 memset(a,0,sizeof(a));
  63. 63 for(i=1; i<=l+1; i++)
  64. 64 {
  65. 65 if(extend[i]==l)//当匹配数等于l时就相等
  66. 66 {
  67. 67 a[1]++;
  68. 68 }
  69. 69 else
  70. 70 {
  71. 71 if(tt[i+extend[i]]-'0'>cc[extend[i]+1]-'0')//不等于l时比较开始不相等的那位
  72. 72 {
  73. 73 a[0]++;
  74. 74 }
  75. 75 else a[2]++;
  76. 76 }
  77. 77 }
  78. 78 printf("Case %d: ",s);
  79. 79 printf("%d %d %d\n",a[2]/temp,(a[1]-1)/temp,a[0]/temp);
  80. 80
  81. 81 }
  82. 82
  83. 83 }
  84. 84 void next1(int k)
  85. 85 {
  86. 86 int i,j,p;
  87. 87 j=1;
  88. 88 int r=j;
  89. 89 nex[1]=0;
  90. 90 while(cc[j+1]==cc[j]&&j+1<=k)
  91. 91 {
  92. 92 j++;
  93. 93 }
  94. 94 nex[2]=j-r;
  95. 95 int id=2;
  96. 96 for(i=3; i<=k; i++)
  97. 97 {
  98. 98 p=id+nex[id]-1;
  99. 99 int L=nex[i-id+1];
  100. 100 int c=i+L-1;
  101. 101 if(c>=p)
  102. 102 {
  103. 103 int j=p-i+1;
  104. 104 if(j<0)j=0;
  105. 105 while(cc[j+1]==cc[j+i]&&j+i<=k)
  106. 106 {
  107. 107 j++;
  108. 108 }
  109. 109 nex[i]=j;
  110. 110 id=i;
  111. 111 }
  112. 112 else nex[i]=L;
  113. 113 }
  114. 114 }
  115. 115
  116. 116 void EXkmp(int k,int r)
  117. 117 {
  118. 118 int i,j;
  119. 119 j=0;
  120. 120 while(cc[j+1]==tt[j+1]&&j+1<=r)
  121. 121 {
  122. 122 j++;
  123. 123 }
  124. 124 extend[1]=j;
  125. 125 int id=1;
  126. 126 int p;
  127. 127 for(i=2; i<=k; i++)
  128. 128 {
  129. 129 p=id+extend[id]-1;
  130. 130 int L=nex[i-id+1];
  131. 131 int c=i+L-1;
  132. 132 if(c>=p)
  133. 133 {
  134. 134 j=p-i+1;
  135. 135 j=max(j,0);
  136. 136 while(cc[j+1]==tt[j+i]&&j+i<=k&&j<=r)
  137. 137 {
  138. 138 j++;
  139. 139 }
  140. 140 extend[i]=j;
  141. 141 id=i;
  142. 142 }
  143. 143 else extend[i]=L;
  144. 144 }
  145. 145 }
 

Revolving Digits(hdu4333)的更多相关文章

  1. 【HDU4333】Revolving Digits(扩展KMP+KMP)

    Revolving Digits   Description One day Silence is interested in revolving the digits of a positive i ...

  2. HDU - 4333 :Revolving Digits (扩展KMP经典题,问旋转后有多少个不同的数字小于它本身,等于它本身,大于它本身。)

    One day Silence is interested in revolving the digits of a positive integer. In the revolving operat ...

  3. HDU - 4333 Revolving Digits(扩展KMP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意 一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意 ...

  4. HDU - 4333 Revolving Digits(拓展kmp+最小循环节)

    1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...

  5. Revolving Digits(hdu 4333)

    题意:就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个.比如341-->134-->413-->3 ...

  6. CodeForces 489C Given Length and Sum of Digits... (贪心)

    Given Length and Sum of Digits... 题目链接: http://acm.hust.edu.cn/vjudge/contest/121332#problem/F Descr ...

  7. Codeforces 915 C. Permute Digits (dfs)

    题目链接:Permute Digits 题意: 给出了两个数字a,b(<=1e18),保证a,b都不带前缀0.用a的字符重组一个数字使这个值最大且小于b.(保证这个值存在) 题解: 这题遇到了不 ...

  8. CodeForces 489C Given Length and Sum of Digits... (dfs)

    C. Given Length and Sum of Digits... time limit per test 1 second memory limit per test 256 megabyte ...

  9. UVA-10061 How many zero's and how many digits ? (数论)

    题目大意:让求n!在base进制下的位数以及末尾0的连续个数. 题目分析:一个m位的b进制数N,最小是b^(m-1),最大不超过b^m,即b^(m-1)≤N<b^m.解不等式,得log10(N) ...

随机推荐

  1. 【MarkDown】--使用教程

    MarkDown使用教程 目录 MarkDown使用教程 一. 常用设置 1.1 目录 1.2 标题 1.3 文本样式 (1)引用 (2)高亮 (3)强调 (4)水平线 (5)上下标 (6)插入代码 ...

  2. org.apache.hadoop.hive.ql.metadata.HiveException: Internal Error: cannot generate all output rows for a Partition解决

    自己在路径访问明细表开发时,写的sql如下 SELECT guid, sessionid, event['url'] as page, `timestamp` as ts, row_number() ...

  3. ubuntu18.10搜狗输入法的安装

    记录一下 1.卸载ibus ubuntu默认使用ibus管理输入法,官方推荐使用fcitx.我们先卸载ibus sudo apt-get remove ibus 清除ibus配置,如果没有设置 sud ...

  4. oracle(创建数据库对象)

    1 --创建数据库 2 --1.SYSDBA系统权限 3 startup:--启动数据库. 4 shutdown:--关闭数据库. 5 alter database[mount]|[open]|[ba ...

  5. RHEL 6.5安装系统

    转自如下链接: http://www.jb51.net/os/128752.html

  6. Linux:find命令中

    默认情况下, find 每输出一个文件名, 后面都会接着输出一个换行符 ('\n'), 因此我们看到的 find 的输出都是一行一行的: ls -l total 0 -rw-r--r-- 1 root ...

  7. Spring Boot中使用Mybatis

    一.步骤 导入依赖:MySQL驱动.Druid依赖.MyBatis与Spring Boot整合依赖.Lombok依赖 在Service接口实现类上添加@Service注解 在Dao接口上添加@Mapp ...

  8. 【Services】【Web】【LVS】lvs基础概念

    1.简介 1.1. 作者:张文嵩,就职于阿里 1.2. LVS是基础四层路由.四层交换的软件,他根据请求报文的目标IP和目标PORT将其调度转发至后端的某主机: 1.3. IPTABLES的请求转发路 ...

  9. Linux(CentOS 7)使用gcc编译c,c++代码

    安装gcc: 1.使用 yum -list gcc* 查询 centos 官方gcc的所有包: 可安装的软件包 gcc.x86_64 gcc-c++.x86_64 gcc-gfortran.x86_6 ...

  10. 【力扣】95. 不同的二叉搜索树 II

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...