USACO: Cryptcowgraphy

本文介绍了一种由农场里的牛们发明的加密方法,用于保护它们的秘密通讯。该加密方式通过随机插入特定字符并交换部分字符串实现。文章详细讨论了解密算法的设计与实现,包括深度优先搜索剪枝策略及字符串哈希技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cryptcowgraphy
Brian Dean

The cows of Farmer Brown and Farmer John are planning a coordinated escape from their respective farms and have devised a method of encryption to protect their written communications.

Specifically, if one cow has a message, say, "International Olympiad in Informatics", it is altered by inserting the letters C, O, and W, in random location in the message, such that C appears before O, which appears before W. Then the cows take the part of the message between C and O, and the part between O and W, and swap them. Here are two examples:

            International Olympiad in Informatics
                              -> 
            CnOIWternational Olympiad in Informatics
            
            International Olympiad in Informatics
                              -> 
            International Cin InformaticsOOlympiad W

To make matters more difficult, the cows can apply their encryption scheme several times, by again encrypting the string that results from the previous encryption. One night, Farmer John's cows receive such a multiply-encrypted message. Write a program to compute whether or not the non-encrypted original message could have been the string:

            Begin the Escape execution at the Break of Dawn

PROGRAM NAME: cryptcow

INPUT FORMAT

A single line (with both upper and lower case) with no more than 75 characters that represents the encrypted message.

SAMPLE INPUT (file cryptcow.in)

Begin the EscCution at the BreOape execWak of Dawn

OUTPUT FORMAT

Two integers on a single line. The first integer is 1 if the message decodes as an escape message; 0 otherwise. The second integer specifies the number of encryptions that were applied (or 0 if the first integer was 0).

SAMPLE OUTPUT (file cryptcow.out)

1 1

 

解体思路:

又一道变态搜索题,DFS剪枝(一下特殊字符指COW):

1、比较原始串和加密串的字符,除了COW这三个字母以外,其它字符应该是一样多的

2、COW三个字符的个数应该是一样多的

3、如果没有字符O,直接strcmp判断

4、DFS函数中,检测三个特殊字符是否最左边是C,最右边是W

5、DFS函数中,检测每个最长的不含特殊字符的子串是否存在于原始串中

6、DFS函数中,检测整个字符串是否已经搜索过

 

关于压缩(168~197行):这个是非必要的,我的解释是减少指针,这是因为我开始想用trie树来做标记处理上述剪枝的第6点,事实说明整个长串用trie来标记是不可行的,就算70+个指针压缩成24个指针都还是会爆内存的

 

trie树:trie树你懂的!我主要用来标记上述剪枝的第5点

 

到底怎么hash:

传说字符串用elf来哈希就可以过,不过我看了一下实现代码,太多冲突了,没处理好的话,这道题的终极数据还是要0.9XX过,我一直想弄一个没有冲突的hash出来。

想来想去hash不出来,用trie树试试吧,上面提到,trie准确率是高了,只是在第6还是哪一个数据开始爆内存了。

再想想,完全没有必要整串trie啊,因为里面那些“最长的不含特殊字符的子串”已经存在于trie树中了,我只处理特殊字符,然后把指针回指到root下。这一下内存问题解决了,但是又出一个问题,第9组数据wa了,分析一下,这个方法还是有漏洞的,不过挺难表达,自己理解吧。

还真多亏usaco的数据全面呐,不然全过了的话这个漏洞我就发现不了了。最后再加一点点easy Hash判断,easy Hash有trie的辅助确实很easy,每次判断完“最长的不含特殊字符的子串”,hashIdx += (dfsHlp->b * 100 + dfsHlp->e);问题果然就解决了,效率也比较满意了,哎~~~

 

搞了好久,必须臭美一下贴贴成绩O(∩_∩)O哈哈~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值