USACO 4.1.4 cryptcow
题目:
http://ace.delos.com/usacoprob2?a=0H14tt2CoyP&S=cryptcow
http://pingce.ayyz.cn:9000/usaco/data/20110129214306/index.html#Section_5.1
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
题解:
USACO又一道神级恶心搜索题,题意是插入COW进行加密后问能否解密。如对abcdef,加密后可变为aCdeOabWf,此即为加密方式。
搜索吧………………………………但是必须优化啊……………………
优化:
1、优先枚举O的位置。
2、检验每两个特殊字符间的字串是否为目标字串子串。
3、不推荐链表,虽然交换是O(1)的,但不好写,也不好调,错了要哭的………………而且查找起来就有慢了………………
4、hash判重………………这方法其实不科学,有科学的hash法,但对这道题不适用……………………
难写,难调,如果你不想浪费时间,别写它了。如果你想练代码能力,写写吧。
1 /*
2 ID:zhongha1
3 PROB:cryptcow
4 LANG:C++
5 */
6
7 #include<cstdio>
8 #include<cstdlib>
9 #include<cstring>
10
11 using namespace std;
12
13 char goal[100]=" Begin the Escape execution at the Break of Dawn";
14
15 const int mo=1000003;
16
17 int sl,final;
18
19 char s[100],help[100];
20
21 bool hash[mo];
22
23 int get_hash(char *s,int l)
24 {
25 int v=0,seed=131313;
26 for (int a=1;a<=l;a++)
27 v=(v*seed+s[a]) % mo;
28 return (v & 0x7FFFFFFF) % mo;
29 }
30
31 void change(char *s,int c,int o,int w,int nowl)
32 {
33 memset(help,0,sizeof(help));
34 int l=0;
35 for (int a=1;a<c;a++)
36 {
37 l++;
38 help[l]=s[a];
39 }
40 for (int a=o+1;a<w;a++)
41 {
42 l++;
43 help[l]=s[a];
44 }
45 for (int a=c+1;a<o;a++)
46 {
47 l++;
48 help[l]=s[a];
49 }
50 for (int a=w+1;a<=nowl;a++)
51 {
52 l++;
53 help[l]=s[a];
54 }
55 strcpy(s+1,help+1);
56 }
57
58 bool cut(char *s,int l)
59 {
60 int nowl=0;
61 int fp=1;
62 while (s[fp]!='C' & s[fp]!='O' && s[fp]!='W')
63 {
64 if (s[fp]!=goal[fp]) return true;
65 fp++;
66 }
67 if (s[fp]!='C') return true;
68 int lp=l,hehe=47;
69 while (s[lp]!='C' && s[lp]!='O' && s[lp]!='W')
70 {
71 if (s[lp]!=goal[hehe]) return true;
72 lp--;
73 hehe--;
74 }
75 if (s[lp]!='W') return true;
76 int lastp=fp,nowp=fp+1;
77 while (nowp<=lp)
78 {
79 if (s[nowp]=='C' || s[nowp]=='O' || s[nowp]=='W')
80 {
81 nowl=0;
82 for (int a=lastp+1;a<nowp;a++)
83 {
84 nowl++;
85 help[nowl]=s[a];
86 }
87 bool exist=false;
88 for (int a=1;a+nowl-1<=47;a++)
89 {
90 for (int b=1;b<=nowl;b++)
91 if (help[b]!=goal[a+b-1]) break;
92 else
93 {
94 if (b==nowl) exist=true;
95 }
96 if (exist) break;
97 }
98 if (lastp+1!=nowp)
99 if (!exist) return true;
100 lastp=nowp;
101 }
102 nowp++;
103 }
104 return false;
105 }
106
107 bool dfs(char *s,int d)
108 {
109 int nowv=get_hash(s,sl-d*3);
110 if (hash[nowv]) return false;
111 if (nowv==final) return true;
112 hash[nowv]=true;
113 if (cut(s,sl-d*3)) return false;
114 char help[100];
115 for (int o=1;o<=sl-d*3;o++)
116 if (s[o]=='O')
117 {
118 for (int c=1;c<o;c++)
119 if (s[c]=='C')
120 {
121 for (int w=sl-d*3;w>o;w--)
122 if (s[w]=='W')
123 {
124 strcpy(help+1,s+1);
125 change(help,c,o,w,sl-d*3);
126 if (dfs(help,d+1)) return true;
127 }
128 }
129 }
130 return false;
131 }
132
133 int main()
134 {
135 freopen("cryptcow.in","r",stdin);
136 freopen("cryptcow.out","w",stdout);
137
138 int nowl=0;
139 char orz='!';
140 while (orz!='\r' && orz!='\n')
141 {
142 scanf("%c",&orz);
143 nowl++;
144 s[nowl]=orz;
145 }
146 s[nowl]='\0';
147 nowl--;
148 sl=nowl;
149 final=get_hash(goal,47);
150 if ((nowl-47)%3!=0)
151 {
152 printf("0\n");
153 return 0;
154 }
155 if (dfs(s,0)) printf("1 %d\n",(nowl-47)/3);
156 else printf("0 0\n");
157
158 return 0;
159 }