USACO Section 4.1 Cryptcowgraphy - BT的DFS剪枝..
来源:互联网 发布:linux如何关闭防火墙 编辑:程序博客网 时间:2024/05/16 10:33
开始做的时候就想到是搜索...写完了样例就跑过了..然后提交就超时..后来再一想..裸搜时间复杂度高得惊人阿..做了几个优化..还是N久跑不出结果...我以为搜索是搜不过的...就想用其他方法来解决..但纠结了很久也没有个明确方向..
写了一天..实在是没辙了..就去网上搜了下解题报告..发现其实是搜索~~关键还是在于剪枝~~~我原来的搜索剪枝真是弱爆了..
1.C.O.W这三个字符任意两个中间的无C.O.W的字符串一定要是原串的子串才合法..因为在后面做任何变化这一段都是改变不了的了..
2.差不多和上面那个一个意思..就是最前面没有任何C.O.W的一截必须和原串的前面这截相等..尾部一样..同上理..
3.C.O.W这些字符出现在最左边的一定是C,出现在最右边的一定是W..
4.在DFS过程中会有很多重复的搜索..这里就要通过Hash来判重..我的Hash方法..见我的Turn函数..自创的说..
5.很诡异的..在别人那看到的..想不出有什么道理..但却是速度提升很多..或许是题目数据的特殊所至~~
先确定O..再确定C..再确定W...在确定W时从后往前扫~~
还有就是字符串用char[]来处理比string来处理速度至少快3倍阿~~
这道题用了几个以前很少用到的字符串函数,这次也熟悉了下...如
strcmp(s1,s2)是比较两串..当且仅当strcmp的返回值是0的时候s1与s2相等...
strncat(s1,s2,k)将s2的前k位加到s1的后面..如果要中间的一段..strncat(s1,s2+i,j)就行了
Program:
/* ID: zzyzzy12 LANG: C++ TASK: cryptcow*/ #include<iostream> #include<istream> #include<stdio.h> #include<string.h> #include<math.h> #include<stack>#include<map>#include<algorithm> #include<queue> #define oo 2000000000 #define ll long long #define pi (atan(2)+atan(0.5))*2using namespace std; char str[50]="Begin the Escape execution at the Break of Dawn",s[305];int lenstr=strlen(str),x,Prime[505],num; string ss1=str;bool f,hash[500005];int Turn(char *s){ int i,k=0,l=strlen(s); s[l]='a'; for (i=0;i<l;i++) { k+=Prime[i+1]*s[i]*(s[i]+s[i+1]); k%=500000; } s[l]='\0'; return k; } void DFS(char *s,int p){ int i,j,k,t,l=strlen(s); char s1[305]; x=Turn(s); if (hash[x]) return; hash[x]=true; if (!strcmp(s,str)) { f=true; printf("1 %d\n",p); return; } //-------------------判断末尾一截是否相等------------------ t=lenstr; i=l; while (s[i]!='C' && s[i]!='O' && s[i]!='W') { if (s[i]!=str[t]) return; t--; i--; } if (s[i]!='W') return; //------------------判断前面一截是否相等------------------- i=0; while (s[i]!='C' && s[i]!='O' && s[i]!='W') { if (s[i]!=str[i]) return; i++; } if (s[i]!='C') return; //-------------判断C,O,W中间的串是否在所求串中存在--------- s1[0]='\0'; for (i++;i<l;i++) if (s[i]=='C' || s[i]=='O' || s[i]=='W') { if (ss1.find(s1)==-1) return; s1[0]='\0'; }else strncat(s1,s+i,1); //----------------------------------------- for (j=0;j<l;j++) if (s[j]=='O') for (i=0;i<j;i++) if (s[i]=='C') for (k=l-1;k>j;k--) if (s[k]=='W') { s1[0]='\0'; strncat(s1,s,i); strncat(s1,s+j+1,k-j-1); strncat(s1,s+i+1,j-i-1); strncat(s1,s+k+1,l-k-1); DFS(s1,p+1); if (f) return; } }int main() { freopen("cryptcow.in","r",stdin); freopen("cryptcow.out","w",stdout); gets(s); while (s[strlen(s)-1]==' ') s[strlen(s)-1]='\0'; f=false; memset(hash,false,sizeof(hash)); num=0; for (int i=3;i>0;i++) { for (int j=2;j*j<=i;j++) if (i%j==0) goto A; Prime[++num]=i; if (num==500) break; A: ; } DFS(s,0); if (!f) printf("0 0\n"); return 0; }
- USACO Section 4.1 Cryptcowgraphy - BT的DFS剪枝..
- USACO 4.1 Cryptcowgraphy dfs+剪枝
- usaco 4.1 Cryptcowgraphy(DFS+hash+剪枝)
- usaco 4.1 Cryptcowgraphy 剪枝
- usaco 4.1.4 Cryptcowgraphy 搜索剪枝
- usaco 4.1 Cryptcowgraphy
- [usaco] 4.1.4 PROB Cryptcowgraphy
- USACO Section 5.4 All Latin Squares - DFS剪枝,我只能做出5个点..
- POJ1164 + USACO Section 2.1 The Castle - 简单的DFS...
- USACO 1.5 Checker Challenge (DFS + 剪枝)
- USACO 6.3.3 Cowcycles dfs+剪枝
- hdoj--4277--USACO ORZ(dfs+剪枝)
- HDOJ 4277 USACO ORZ DFS+剪枝
- usaco shuttle puzzle(dfs剪枝)
- 洛谷 2210 [USACO] Haywire dfs+剪枝
- USACO Section 4.4 Frame Up - DFS即可~
- USACO section 1.5 Checker Challenge(dfs深搜)
- USACO section 2.1 The Castle(dfs)
- 使用Jackson解析json配合Hibernate报错的解决方法
- Linux多线程编程(转载于吴秦前辈)
- 迪拜酒店内豹纹鲨连续四年单性繁殖
- gdb常用命令abc
- Notepad++ plugin(插件)开发之消息HOOK (文件保存,文件打开,文件关闭)
- USACO Section 4.1 Cryptcowgraphy - BT的DFS剪枝..
- word应用:Word2007表格中快速填充编号序列
- Types of permissions (MDB) zz
- 常用的HTML标签和属性解释
- php中foreach()函数的用法
- unable to open “frameworks\locale\zh_CN’ 解决方法
- 技嘉X79 UD3主板再创Intel reg X79超频世界纪录
- 黑马-----银行业务调度系统
- HTML5学习资源