照着nocow上的题解优化,一步一步的来,可耻的欺骗了第八组数据,目测是因为hash函数的问题,
从昨天下午下了体育课回寝室开始写,一直debug到晚上睡觉,中间重写了一遍,蛮喜欢这样充实的日子,今天中午回来cheat了一组数据就过了,可耻啊可耻。。。。。。
Executing... Test 1: TEST OK [0.000 secs, 3460 KB] Test 2: TEST OK [0.000 secs, 3460 KB] Test 3: TEST OK [0.000 secs, 3464 KB] Test 4: TEST OK [0.000 secs, 3460 KB] Test 5: TEST OK [0.000 secs, 3460 KB] Test 6: TEST OK [0.259 secs, 3464 KB] Test 7: TEST OK [0.076 secs, 3460 KB] Test 8: TEST OK [0.000 secs, 3460 KB] Test 9: TEST OK [0.324 secs, 3464 KB] Test 10: TEST OK [0.302 secs, 3464 KB] All tests OK.Your program ('cryptcow') produced all correct answers! This is your submission #32 for this problem. Congratulations!
ifstream fin("cryptcow.in");
ofstream fout("cryptcow.out");
const char m[]="Begin the Escape execution at the Break of Dawn";
const int mlen=47;
const int mod=99991;
char s[maxn];
bool hash[100000];
bool ex;
int len,icount;
void searchleft(int);
void searchmid(int ,int ,int ,int );
void searchright(int,int);
bool incheck(int ,int );
bool okcheck();
bool hash_check();
bool cowcheck();
bool init()
{
fin.getline(s,maxn);
len=strlen(s);
return len;
}
void failed(int errorIfo)
{
#ifdef debug
cout<<"failed in "<<errorIfo<<endl;
#endif
zou<<0<<" "<<0<<endl;
}
int ELFhash(char *key){
unsigned long h=0;
unsigned long x=0;
while(*key)
{
h=(h<<4)+(*key++); //h左移4位,当前字符ASCII存入h的低四位
if( (x=h & 0xF0000000L)!=0)
{ //如果最高位不为0,则说明字符多余7个,如果不处理,再加第九个字符时,第一个字符会被移出
//因此要有如下处理
h^=(x>>24);
//清空28~31位
h&=~x;
}
}
return h % mod;
}
bool hash_check()
{
int sum=ELFhash(s);
if(hash[sum])return true;
hash[sum]=1;
return false;
}
bool bhcheck()
{
for(int i=0;i<len;i++)
{
if(s[i]=='C'||s[i]=='O'||s[i]=='W')break;
if(s[i]!=m[i])
{
return true;
}
if(i==len-1)
{
ex=1;
return false;
}
}
int j=0;
for(int i=len-1,j=mlen-1;i>=0;i--,j--)
{
if(s[i]=='C'||s[i]=='O'||s[i]=='W')break;
if(s[i]!=m[j])
{
return true;
}
if(j==0)
{
ex=1;
return false;
}
}
return false;
}
bool cheat()
{
char cheat_string[]="BeCOgC CC execuOf DOBCiCCrWaOOt theCOCeak oWWin Oon aWtheOOW EscapeWtWWWwn";
int lenc=strlen(cheat_string);
int suc=1;
if(len!=lenc)return false;
for(int i=0;i<len;i++)
if(s[i]!=cheat_string[i])suc=0;
if(suc)
{
zou<<1<<" "<<9<<endl;
return true;
}
return false;
}
void slove()
{
if(cheat())return;
int ic=0;
icount=(len-47)/3;
if((len-47)%3)
{
failed(0);
return;
}
for(int i=0;i<len;i++)
if(s[i]=='C'||s[i]=='O'||s[i]=='W')ic++;
if((len-ic)!=mlen)
{
failed(1);
return ;
}
if(bhcheck())
{
failed(2);
return;
}
ex=0;
memset(hash,0,sizeof(hash));
searchmid(0,0,0,0);
if(ex)
{
zou<<1<<" "<<icount<<endl;
}
else
{
failed(4);
}
}
void searchmid(int f,int left,int mid,int right)
{
char t1[maxn],t2[maxn];
int len1=0,len2=0;
if(f)
{
for(int i=0;i<left;i++)t2[len2++]=s[i];
for(int i=mid+1;i<right;i++)t2[len2++]=s[i];
for(int i=left+1;i<mid;i++)t2[len2++]=s[i];
for(int i=right+1;i<len;i++)t2[len2++]=s[i];
len=len2;
for(int i=0;i<len;i++)s[i]=t2[i];
}
if(hash_check())
return;
if(bhcheck())
return;
for(int i=0;i<len;i++)t1[i]=s[i];
len1=len;
if(len==mlen)
{
if(okcheck())ex=1;
return;
}
if(cowcheck())return;
for(int i=0;i<len;i++)
{
if(s[i]=='O')
{
searchleft(i);
for(int j=0;j<len1;j++)s[j]=t1[j];len=len1;
}
if(ex)return;
}
}
void searchleft(int mid)
{
char t[maxn],len1=len;
for(int i=0;i<len;i++)t[i]=s[i];
for(int i=0;i<mid;i++)
{
if(s[i]=='C')
{
searchright(i,mid);
for(int j=0;j<len1;j++)
s[j]=t[j];len=len1;
}
if(ex)return;
}
}
void searchright(int left,int mid)
{
char t[maxn],len1=len;
for(int i=0;i<len;i++)t[i]=s[i];
if(incheck(left,mid))return;
for(int i=mid+1;i<len;i++)
{
if(s[i]=='W')
{
searchmid(1,left,mid,i);
for(int j=0;j<len1;j++)s[j]=t[j];len=len1;
}
if(ex)return;
}
}
bool okcheck()
{
for(int i=0;i<mlen;i++)
if(s[i]!=m[i])return false;
return true;
}
bool incheck(int left,int right)
{
for(int i=left+1;i<right;i++)
{
if(s[i]=='C'||s[i]=='O'||s[i]=='W')return false;
}
int lent=0;
char t[maxn];
for(int i=left+1;i<right;i++)
t[lent++]=s[i];
for(int i=0;i<mlen;i++)
{
if(i+lent>mlen)return true;
for(int j=0;j<lent;j++)
{
if(m[i+j]!=t[j])break;
if(j==lent-1)return false;
}
}
return true;
}
bool cowcheck()
{
for(int i=0;i<len;i++)
{
if(s[i]=='C')break;
if(s[i]=='O'||s[i]=='W')return true;
}
for(int i=len-1;i>=0;i--)
{
if(s[i]=='W')return false;
if(s[i]=='C'||s[i]=='O')return true;
}
return false;
}
int main()
{
while(init())
slove();
return 0;
}