题目大意:

定义字符串的hash值\(h = \sum_{i=0}^{n-1}p^{n-i-1}s_i\)

现在给定K个长度不超过L的字符串S,对于每个字符串S,求字典序最小长度不超过L的字符串T使得T不同于S但是Hash值相同.\(P\leq 2^{31},L \leq 8,K \leq 15\)

题解:

我们考虑直接爆搜\(O(26^L)\)

肯定过不了啊。。。

但是我们发现,如果我们枚举前L-1位,那么最后一位可以直接计算出来.

所以可以做到\(O(26^{L-1})\)

我们再进一步,如果我们枚举前L-4位,后4位我们打表预处理出来。

可以做到\(O(26^(L-4)log26^4)\)

我们发现这个复杂度妥妥地能过。

但是嘛。。。也许是我写丑了。。。本地跑的特别慢但是bzoj能A...

这道题就是个大毒瘤,写了一下午!

  1. #include <map>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. typedef unsigned int uint;
  8. inline void read(uint &x){
  9. x=0;char ch;bool flag = false;
  10. while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
  11. while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
  12. }
  13. const int maxn = 22;
  14. uint P,L,K,n;
  15. char ss[26*26*26*26 + 26*26*26 + 26*26 + 26 + 10][6];
  16. uint cnt = 0;
  17. inline uint qpow(uint x,uint p){
  18. uint ret = 1;
  19. for(;p;x=x*x,p>>=1) if(p&1) ret=ret*x;
  20. return ret;
  21. }
  22. char s[maxn];
  23. inline uint hash(char *s,uint n){
  24. uint ret = 0;
  25. for(uint i=0;i<n;++i){
  26. ret += (uint)s[i]*qpow(P,n-i-1);
  27. }
  28. return ret;
  29. }
  30. uint val;bool flag;
  31. char t[maxn];uint len;
  32. char ans[maxn];
  33. inline void judge(uint m){
  34. bool cp = false;
  35. if(n != m) cp = true;
  36. else for(uint i=0;i<n;++i) if(s[i] != t[i]) cp = true;
  37. if(!cp) return;
  38. if(hash(t,m) == val){
  39. if(!flag){
  40. flag = true;len = m;
  41. for(uint i = 0;i<len;++i){
  42. ans[i] = t[i];
  43. }
  44. }else{
  45. bool sw = false;
  46. for(uint i = 0;i<len && i < m;++i){
  47. if(t[i] < ans[i]){
  48. sw = true;
  49. break;
  50. }
  51. }
  52. if(sw || (!sw && m < len)){
  53. for(uint i=0;i<m;++i){
  54. ans[i] = t[i];
  55. }len = m;
  56. }
  57. }
  58. }
  59. }
  60. inline void judge(char* t){
  61. int m = strlen(t);
  62. bool cp = false;
  63. if(n != m) cp = true;
  64. else for(uint i=0;i<n;++i) if(s[i] != t[i]) cp = true;
  65. if(!cp) return;
  66. if(hash(t,m) == val){
  67. if(!flag){
  68. flag = true;len = m;
  69. for(uint i = 0;i<len;++i){
  70. ans[i] = t[i];
  71. }
  72. }else{
  73. bool sw = false;
  74. for(uint i = 0;i<len && i < m;++i){
  75. if(t[i] < ans[i]){
  76. sw = true;
  77. break;
  78. }
  79. }
  80. if(sw || (!sw && m < len)){
  81. for(uint i=0;i<m;++i){
  82. ans[i] = t[i];
  83. }len = m;
  84. }
  85. }
  86. }
  87. }
  88. inline void calc(uint m){
  89. uint x = hash(t,m);
  90. x = x*P;
  91. uint y = val - x;
  92. t[m] = y;
  93. if(y >= 'A' && y <= 'Z')judge(m+1);
  94. }
  95. void dfs(uint pos){
  96. if(pos == L-1){
  97. calc(pos);
  98. return;
  99. }
  100. for(char ch='A';ch<='Z';++ch){
  101. t[pos] = ch;
  102. dfs(pos+1);
  103. if(flag) return;
  104. judge(pos);
  105. if(flag) return;
  106. }
  107. }
  108. char tmp[6];
  109. map<int,int>mp2,mp3,mp4;
  110. char query[maxn][maxn];
  111. inline void save4(){
  112. uint h = hash(tmp,4);
  113. if(mp4[h] == 0){
  114. for(uint i=1;i<=K;++i){
  115. if(!strcmp(tmp,query[i]))
  116. return;
  117. }
  118. ++cnt;
  119. for(uint i=0;i<4;++i){
  120. ss[cnt][i] = tmp[i];
  121. }
  122. mp4[h] = cnt;
  123. }
  124. }
  125. inline void save3(){
  126. uint h = hash(tmp,3);
  127. if(mp3[h] == 0){
  128. for(uint i=1;i<=K;++i){
  129. if(!strcmp(tmp,query[i]))
  130. return;
  131. }
  132. ++cnt;
  133. for(uint i=0;i<3;++i){
  134. ss[cnt][i] = tmp[i];
  135. }
  136. mp3[h] = cnt;
  137. }
  138. }
  139. inline void save2(){
  140. uint h = hash(tmp,2);
  141. if(mp2[h] == 0){
  142. for(uint i=1;i<=K;++i){
  143. if(!strcmp(tmp,query[i]))
  144. return;
  145. }
  146. ++cnt;
  147. for(uint i=0;i<2;++i){
  148. ss[cnt][i] = tmp[i];
  149. }
  150. mp2[h] = cnt;
  151. }
  152. }
  153. inline void dfss(uint pos){
  154. if(pos == 2) save2();
  155. if(pos == 3) save3();
  156. if(pos == 4){
  157. save4();
  158. return ;
  159. }
  160. for(char ch = 'A';ch<='Z';++ch){
  161. tmp[pos] = ch;
  162. dfss(pos+1);
  163. }
  164. }
  165. inline void ca4(uint m){
  166. uint x = hash(t,m);
  167. x = x*P*P*P*P;
  168. uint y = val - x;
  169. for(int i=1;i<=K;++i){
  170. if(strlen(query[i]) == 4){
  171. for(int j=0;j<4;++j){
  172. t[m+j] = query[i][j];
  173. }
  174. judge(m+4);
  175. }
  176. }
  177. if(mp4[y] == 0) return;
  178. for(int i=0;i<4;++i){
  179. t[m+i] = ss[mp4[y]][i];
  180. }
  181. judge(m+4);
  182. }
  183. inline void ca3(uint m){
  184. uint x = hash(t,m);
  185. x = x*P*P*P;
  186. uint y = val - x;
  187. for(int i=1;i<=K;++i){
  188. if(strlen(query[i]) == 3){
  189. for(int j=0;j<3;++j){
  190. t[m+j] = query[i][j];
  191. }
  192. judge(m+3);
  193. }
  194. }
  195. if(mp3[y] == 0) return;
  196. for(int i=0;i<3;++i){
  197. t[m+i] = ss[mp3[y]][i];
  198. }
  199. judge(m+3);
  200.  
  201. }
  202. inline void ca2(uint m){
  203. uint x = hash(t,m);
  204. x = x*P*P;
  205. uint y = val - x;
  206. for(int i=1;i<=K;++i){
  207. if(strlen(query[i]) == 3){
  208. for(int j=0;j<3;++j){
  209. t[m+j] = query[i][j];
  210. }
  211. judge(m+3);
  212. }
  213. }
  214. if(mp2[y] == 0) return;
  215. for(int i=0;i<2;++i){
  216. t[m+i] = ss[mp2[y]][i];
  217. }
  218. judge(m+2);
  219. }
  220. void search(uint pos){
  221. if(pos == L-4){
  222. calc(pos);
  223. ca2(pos);
  224. ca3(pos);
  225. ca4(pos);
  226. return;
  227. }
  228. for(char ch='A';ch<='Z';++ch){
  229. t[pos] = ch;
  230. search(pos+1);
  231. if(flag) return;
  232. judge(pos);
  233. if(flag) return;
  234. }
  235. calc(pos);ca2(pos);ca3(pos);ca4(pos);
  236. }
  237. int main(){
  238. read(P);read(L);read(K);
  239. for(uint i=1;i<=K;++i) scanf("%s",query[i]);
  240. dfss(0);
  241. for(uint i=1;i<=K;++i){
  242. n = strlen(query[i]);
  243. for(uint j=0;j<n;++j) s[j] = query[i][j];
  244. val = hash(s,n);
  245. flag = false;
  246. if(L <= 4) dfs(0);
  247. else search(0);
  248. if(flag) ans[len] = 0,printf("%s\n",ans);
  249. else puts("-1");
  250. }
  251. getchar();getchar();
  252. return 0;
  253. }

bzoj 3752: Hack 预处理+暴力dfs的更多相关文章

  1. hihoCoder 1185 连通性·三(Tarjan缩点+暴力DFS)

    #1185 : 连通性·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 暑假到了!!小Hi和小Ho为了体验生活,来到了住在大草原的约翰家.今天一大早,约翰因为有事要出 ...

  2. Strange Country II 暴力dfs

    这题点的个数(<=50)有限, 所以可以纯暴力DFS去搜索 //#pragma comment(linker, "/STACK:16777216") //for c++ Co ...

  3. UVA129 暴力dfs,有许多值得学习的代码

    紫书195 题目大意:给一个困难的串,困难的串的定义就是里面没有重复的串. 思路:不需要重新对之前的串进行判重,只需要对当前的加入的字符进行改变即可. 因为是判断字典序第k个的字符串,所以要多一个全局 ...

  4. 2018杭电多校第五场1002(暴力DFS【数位】,剪枝)

    //never use translation#include<bits/stdc++.h>using namespace std;int k;char a[20];//储存每个数的数值i ...

  5. A. The Fault in Our Cubes 暴力dfs

    http://codeforces.com/gym/101257/problem/A 把它固定在(0,0, 0)到(2, 2, 2)上,每次都暴力dfs检查,不会超时的,因为规定在这个空间上,一不行, ...

  6. 【BZOJ】1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(暴力dfs+set判重)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1675 一开始我写了个枚举7个点....... 但是貌似... 写挫了. 然后我就写dfs.. 判重好 ...

  7. bzoj 4765 普通计算姬 dfs序 + 分块

    题目链接 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些.普通计算机能计算数列区间和,而普通计算姬能 ...

  8. Codeforces Round #359 (Div. 2) C. Robbers' watch (暴力DFS)

    题目链接:http://codeforces.com/problemset/problem/686/C 给你n和m,问你有多少对(a, b) 满足0<=a <n 且 0 <=b &l ...

  9. UVA 185(暴力DFS)

      Roman Numerals  The original system of writing numbers used by the early Romans was simple but cum ...

随机推荐

  1. ls --color=xxx

      默认的ls是由"ls --color=auto"组成的,假如某个目录中的文件特别多,我不希望显示颜色(可以加快显示),那就需要指定单独的参数. [root@localhost ...

  2. linux下查找指定时间内修改过的或新建的文件

    1.简单命令 # find -type f \( -newermt '2017-04-19 00:00' -a -not -newermt '2017-04-27 23:59' \) 2.简单实现(参 ...

  3. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

    正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...

  4. windows环境下JDK1.8安装

    jdk的安装,在Windows环境下没有什么特殊的选项,只需要“傻瓜式”安装就行(下一步). 如果说有的话,那就是你安装的路径,默认是c盘下的路径,可以根据自己的喜好,安装到自己的意愿目录: 当然,j ...

  5. ubuntu 13.04 设定静态IP

    切换到root用户,然后进入/etc/network目录.备份interfaces文件(备份文件是一个好习惯) 下面编辑interfaces文件,添加如下语句: # Assgin static IP ...

  6. 第14条:尽量用异常来表示特殊情况,而不要返回Nono

    核心知识点: 1.用None这个返回值来表示特殊意义的函数,很容易使调用者犯错,因为None和0以及空字符串之类的值,在条件表达式里都会评估为False. 2.两种方法:二元法:将异常抛给上一级直接报 ...

  7. mysql设计表时出错

    source下面那个字段没有设置类型,类型为空

  8. rails 注释

    view -# js.erb <%# xxxx %> 单行注释

  9. PHP保存数组到文件中的方法

    ThinkPHP自3.1以后的版本,F函数保存数组时先序列化后再保存到文件中,因为我需要使用C方法来读取自定义配置文件,故需要把PHP数组保存到文件中以便C方法读取,PHP保存数组到文件的方法如下: ...

  10. 文字溢出 省略css

     overflow:hidden;   text-overflow:ellipsis;   -o-text-overflow:ellipsis; white-space:nowrap;