博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[USACO 6.3.2] Cryptcowgraphy
阅读量:4982 次
发布时间:2019-06-12

本文共 3513 字,大约阅读时间需要 11 分钟。

题目大意

  现在知道一个字符串"Begin the Escape execution at the Break of Dawn",在其中按顺序插入'C','O','W'.'C'和'O'之间的部分会和'O''W'之间的部分调换.

  给一个字符串,问此字符串是不是又上述变换形成的并输出经历多少次变换.

题解

  这是黑书<<算法艺术与信息学竞赛>>中的一道搜索题.

  很明显,如果朴素的算法是不可能AC的.因此,我们要加入一些优化.

    1.搜索顺序: 听说加入这个剪枝也是会快不少的,我们的循环顺序应该是'O'->'C'->'W',反正就是先中间后两边.

    2.可行性剪枝: 对于固定部分,即此后无论怎么搜都不变的,也就是"COW"其中一个字符到下一个"COW"字符的中间部分,我们可以在原串中先行匹配,如果不匹配那么可以进行剪枝.

    3.重复状态: 顾名思义判重,这得用传说中的ELFhash,我至今没搞懂是什么意思,不过没关系,能用就行.

代码

 

/*TASK:cryptcowLANG:C++*/#include 
#include
using namespace std;const char *S = "Begin the Escape execution at the Break of Dawn";const int lens = strlen(S);const int MODU = 999991;char buf[100];int n, node;bool hash[MODU];bool check(){ int cnt[256], k = 0; memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < lens; ++i) cnt[S[i]]++; for (int i = 0; i < n; ++i) if (buf[i] != 'C' && buf[i] != 'O' && buf[i] != 'W') cnt[buf[i]]--; else k++; for (int i = 0; i < 256; ++i) if (cnt[i]) return false; return k % 3 == 0 && lens == n - k;}bool match(int k){ if (k == n || buf[k] == 'C' || buf[k] == 'O' || buf[k] == 'W') return true; int f[200]; f[0] = f[1] = 0; for (int i = 1; i < n - k; ++i) { int j = f[i]; if (buf[k + i] == buf[k + j]) f[i + 1] = j + 1; else f[i + 1] = 0; } int j = 0; for (int i = 0; i < lens; ++i) { while (j != 0 && S[i] != buf[k + j]) j = f[j]; if (S[i] == buf[k + j]) j++; if (k + j == n || buf[k + j] == 'C' || buf[k + j] == 'O' || buf[k + j] == 'W') return true; } return false;}bool judge(){ for (int i = 0; i < n; ++i) { if (buf[i] == 'W' || buf[i] == 'C' || buf[i] == 'O') { if (buf[i] == 'C') break; if (buf[i] == 'O' || buf[i] == 'W') return false; } else if (buf[i] != S[i]) return false; } for (int i = 0; i < n; ++i) if (buf[i] == 'C' || buf[i] == 'O' || buf[i] == 'W') if (!match(i + 1)) return false; return true;}int ELFhash(char *str){ unsigned int h = 0, g; while (*str) { h = (h << 4) + (*str++); if (g = h & 0xf0000000l) { h ^= g >> 24; } h &= ~g; } return h % MODU;}bool dfs(int dep){ unsigned int h = ELFhash(buf); if (hash[h]) return false; hash[h] = true; if (!strcmp(buf, S)) { printf("1 %d\n", dep); return true; } char now[100]; int len = n; memcpy(now, buf, sizeof(buf)); for (int j = 0; j < len; ++j) if (now[j] == 'O') for (int i = 0; i < j; ++i) if (now[i] == 'C') for (int k = len - 1; k > j; --k) if (now[k] == 'W') { n = 0; for (int lv = 0; lv < i; ++lv) buf[n++] = now[lv]; for (int lv = j + 1; lv < k; ++lv) buf[n++] = now[lv]; for (int lv = i + 1; lv < j; ++lv) buf[n++] = now[lv]; for (int lv = k + 1; lv < len; ++lv) buf[n++] = now[lv]; buf[n] = '\0'; if (judge() && dfs(dep + 1)) return true; } return false;}int main(){ freopen("cryptcow.in", "r", stdin); freopen("cryptcow.out", "w", stdout); fgets(buf, 100, stdin); n = strlen(buf) - 1; buf[n] = '\0'; node = 0; memset(hash, false, sizeof(hash)); if (!check() || !judge() || !dfs(0)) printf("0 0\n"); return 0;}

 

转载于:https://www.cnblogs.com/albert7xie/p/5736098.html

你可能感兴趣的文章
Fireworks基本使用
查看>>
Java基础常见英语词汇
查看>>
UINavigationController的视图层理关系
查看>>
POJ 1308 Is It A Tree?(并查集)
查看>>
N进制到M进制的转换问题
查看>>
php PDO (转载)
查看>>
[置顶] 一名优秀的程序设计师是如何管理知识的?
查看>>
highcharts曲线图
查看>>
extjs动态改变样式
查看>>
宏定义
查看>>
笔记:git基本操作
查看>>
生成php所需要的APNS Service pem证书的步骤
查看>>
HOT SUMMER 每天都是不一样,积极的去感受生活 C#关闭IE相应的窗口 .
查看>>
optionMenu-普通菜单使用
查看>>
【MemSQL Start[c]UP 3.0 - Round 1 C】 Pie Rules
查看>>
Ognl中“%”、“#”、“$”详解
查看>>
我对应用软件——美团的看法
查看>>
python第六篇文件处理类型
查看>>
ubuntu16系统磁盘空间/dev/vda1占用满的问题
查看>>
grid网格布局
查看>>