usaco--cryptcow

照着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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值