http://codevs.cn/problem/2083/

奶牛搜索题。我加了如下剪枝:

1.用字符串hash判重。注意判重时也要对字符串长度判重,否则会出现两个字符串长度不同但hash值相同的情况,非常容易被卡hash。

2.先枚举O,再枚举C,W。枚举W时从后往前枚举。从网上的题解里看到的,具体为什么我也不知道(捂脸)。

3.对于所有的C,O,W字母可以将字符串切成好几段,但是无论我们怎么交换C-O之间和O-W之间的字符串,这些小段字符串是不会被分开的。所以对于每一个状态我们判断所有C,O,W切成的小段是否在目标串中出现过。这是非常厉害的剪枝。

4.剪枝3只是判断某些字符串小段是否在目标串中出现过,还可以对这些小段的第一段和最后一段加强限制。即当前串的最小的结尾字符的后一个字符是C的前缀必须是目标串的前缀,当前串最小的开头字符的前一个字符是W的后缀必须是目标串的后缀。这也是非常重要的剪枝。

有了上面四个剪枝就可以通过此题了。貌似少一个剪枝就会TLE。

搜索难在分析其玄学的复杂度QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int w = 140;
const int p = 1000007;
const char s[48] = {' ','B','e','g','i','n',' ','t','h','e',' ','E','s','c','a','p','e',' ','e','x','e','c','u','t','i','o','n',' ','a','t',' ','t','h','e',' ','B','r','e','a','k',' ','o','f',' ','D','a','w','n'}; bool showed[9][p + 3];
int n, Pw[80], hash[50], step; int gethash(int l, int r) {
return (int) ((1ll * hash[r] - 1ll * hash[l - 1] * Pw[r - l + 1] % p + p) % p);
} bool flag = false; bool shown(int ha, int len) {
for(int i = len; i <= 47; ++i)
if (gethash(i - len + 1, i) == ha) return true;
return false;
} void dfs(int tmp, char *c, int tot) {
if (tmp > step) {
for(int i = 1; i <= 47; ++i)
if (s[i] != c[i]) return;
flag = true; return;
} int ret = 0;
for(int i = 1; i <= tot; ++i) ret = (int) ((1ll * ret * w + (int) c[i]) % p);
if (showed[tmp - 1][ret]) return;
showed[tmp - 1][ret] = true; ret = 1;
while (c[ret] != 'C' && c[ret] != 'O' && c[ret] != 'W' && ret <= tot) {
if (c[ret] != s[ret]) ret = tot + 2;
++ret;
}
if (ret == tot + 2) return;
if (ret != tot + 1 && c[ret] != 'C') return;
ret = 0;
while (c[tot - ret] != 'C' && c[tot - ret] != 'O' && c[tot - ret] != 'W' && ret < tot) {
if (c[tot - ret] != s[47 - ret]) ret = tot + 2;
++ret;
}
if (ret == tot + 2) return;
if (ret != tot && c[tot - ret] != 'W') return; int head = 1;
for(int i = 1; i <= tot; ++i)
if (c[i] == 'C' || c[i] == 'O' || c[i] == 'W') {
if (head < i) {
ret = 0;
for(int j = head; j < i; ++j) ret = (int) ((1ll * ret * w + (int) c[j]) % p);
if (!shown(ret, i - head)) return;
}
head = i + 1;
} char ch[76];
for(int i = 1; i <= tot; ++i)
if (c[i] == 'O')
for(int j = 1; j < i; ++j)
if (c[j] == 'C')
for(int k = tot; k > i; --k)
if (c[k] == 'W') {
ret = 0;
for(int l = 1; l < j; ++l) ch[++ret] = c[l];
for(int l = i + 1; l < k; ++l) ch[++ret] = c[l];
for(int l = j + 1; l < i; ++l) ch[++ret] = c[l];
for(int l = k + 1; l <= tot; ++l) ch[++ret] = c[l];
dfs(tmp + 1, ch, ret);
if (flag) return;
}
} char c[80]; int main() {
gets(c + 1);
n = strlen(c + 1);
Pw[0] = 1;
for(int i = 1; i <= n; ++i)
Pw[i] = (int) (1ll * Pw[i - 1] * w % p);
hash[0] = 0;
for(int i = 1; i <= 47; ++i)
hash[i] = (int) ((1ll * hash[i - 1] * w + (int) s[i]) % p); step = (n - 47) / 3;
dfs(1, c, n); if (flag) printf("%d %d\n", 1, step);
else puts("0 0"); return 0;
}

调了一下午+一晚上

【CodeVS 2083】Cryptcowgraphy 解密牛语的更多相关文章

  1. 163. [USACO Mat07] 牛语

    ☆   输入文件:latin.in   输出文件:latin.out   简单对比 时间限制:1 s   内存限制:128 MB 译: zqzas 奶牛们听说猪发明了一种秘密语言,叫做"猪语 ...

  2. COGS 163 [USACO Mat07] 牛语

    COGS 163 [USACO Mat07] 牛语 输入文件:latin.in   输出文件:latin.out   简单对比 时间限制:1 s   内存限制:128 MB 奶牛们听说猪发明了一种秘密 ...

  3. bzoj1633 [Usaco2007 Feb]The Cow Lexicon 牛的词典

    Description 没有几个人知道,奶牛有她们自己的字典,里面的有W (1 ≤ W ≤ 600)个词,每个词的长度不超过25,且由小写字母组成.她们在交流时,由于各种原因,用词总是不那么准确.比如 ...

  4. BZOJ 1633: [Usaco2007 Feb]The Cow Lexicon 牛的词典

    题目 1633: [Usaco2007 Feb]The Cow Lexicon 牛的词典 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 401  Solv ...

  5. [USACO07FEB]牛的词汇The Cow Lexicon

    https://daniu.luogu.org/problemnew/show/P2875 dp[i]表示前i-1个字符,最少删除多少个 枚举位置i, 如果打算从i开始匹配, 枚举单词j,计算从i开始 ...

  6. 【BZOJ】1633: [Usaco2007 Feb]The Cow Lexicon 牛的词典(dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1633 一开始也想到了状态f[i]表示i以后的字符串最少删的数 然后想到的转移是 f[i]=min{f ...

  7. 洛谷P2875 [USACO07FEB]牛的词汇The Cow Lexicon

    P2875 [USACO07FEB]牛的词汇The Cow Lexicon 题目描述 Few know that the cows have their own dictionary with W ( ...

  8. 【题解】Luogu P2875 [USACO07FEB]牛的词汇The Cow Lexicon

    题目描述 Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each containing no ...

  9. 2272: [Usaco2011 Feb]Cowlphabet 奶牛文字

    2272: [Usaco2011 Feb]Cowlphabet 奶牛文字 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 138  Solved: 97 ...

随机推荐

  1. 【温故而知新-Javascript】使用 Ajax(续)

    1. 准备向服务器发送数据 Ajax 最常见的一大用途是向服务器发送数据.最典型的情况是从 客户端发送表单数据,即用户在form元素所含的各个 input 元素里输入的值.下面代码展示了一张简单的表单 ...

  2. WinCE项目应用之虚拟仪器(VI)

    虚拟仪器技术就是利用高性能的模块化硬件,结合高效灵活的软件来完成各种测试.测量和自动化的应用.虚拟测量仪器(VI)概念由美国国家仪器公司NI(National Instruments)提出,并引发了传 ...

  3. Remote Displayer for Android V1.2

    VERSION LOG for Android Remote Displayer Features:The app allows you to see your Android device remo ...

  4. NOIP提高组2010 关押罪犯

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...

  5. S2总结笔记

    第一章:深入.NET框架 1..NET FrameWork两大组件是什么? 解析:.NET 框架类库(FCL:FrameWork Class Library)和公共语言运行时(CLR:common l ...

  6. Java synchronized

    1. 将synchronized加在方法上, 即可实现对此方法的同步 public synchronized void deposit(float amt) { float tmp = amount; ...

  7. Delphi项目构成之单元文件PAS

    单元文件是Pascal源文件,扩展名为.pas. 有三种类型的单元文件: 窗体/数据模块和框架的单元文件(form/data module and frame units),一般由Delphi自动生成 ...

  8. Win10删除 6个多余文件夹

    下面附上注册表地址,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace ...

  9. JS给文本框赋值后,在页面后台取不到文本框值的解决方法

    转自:http://www.cnblogs.com/qiaohd/archive/2012/03/23/2413660.html (ReadOnly.disabled 都有可能造成取值取不到) 开发一 ...

  10. 让Bootstrap轮播插件carousel支持左右滑动手势的三种方法

    因为最近开发的项目涉及到移动设备上的 HTML5 开发,其中需要实现轮播效果.然后最快捷的方式,你知道的(Bootstrap),然后原生的 Bootstrap 的 carousel.js 插件并没有支 ...