题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1381
这个题目好像没给n和nc的范围,所以开始用hash有点纠结,不过这个题目还是用纯hash的方法做出来了,没想到还能这么快 15ms
因为数据量比较大,所以hash要想速度很快的话就一定要找到一个计算出hash函数的较快方法,我是按照nc+1进制来的,每次计算新
的hash值的时候就只、需要去除最高位,和加上最低位就能计算出来!
#include <iostream>
#include <string.h>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <stdio.h>
using namespace std;
#define maxn 16000010
bool hash[maxn];
int go[100];
char str[maxn];
int n,nc;
int main()
{
int i,j,k,t;
int len,ans,in;
scanf("%d",&t);
while(t--)
{
in=1;
memset(go,0,sizeof(go));
scanf("%d%d",&n,&nc);
memset(hash,true,sizeof(hash));
scanf("%s",str);
len=strlen(str);
for(i=0;i<len;i++)
if(go[str[i]-'0'+1]==0)
go[str[i]-'0'+1]=in++;
ans=0;
k=0;
if(len<n)
{
printf("0\n");
continue;
}
for(i=0;i<n;i++)
ans=ans*nc+go[str[i]-'0'+1];
hash[ans]=false;
k++;
// cout<<in-1<<endl;
for(i;i<len;i++)
{
ans=ans-(int)pow(nc,n-1)*(go[str[i-n]-'0'+1]);
ans=ans*nc+go[str[i]-'0'+1];
// cout<<ans<<endl;
if(hash[ans]) hash[ans]=false,k++;
}
printf("%d\n",k);
}
return 0;
}
HDU 4662
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4662这个题目就是计算i的个数,i的个数一定是2^k个,先计算出u和i的个数,然后依次用2^k去减,判断结果是否能被6整除
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define maxn 111000
char str[maxn];
bool is_ok(int num_i,int num_u)
{
int count=num_i+num_u*3,i;
long long ans;//printf("%d",count);
if(!(count&(count-1)))
return 1;
i=0;
for(i=0;i<63;i++)
{
ans=pow(2,i);
if(ans>count && (ans-count)%6==0)
return 1;
}
return 0;
}
int main()
{
int t,i,j,k;
bool flag;
int num_u,num_i;
scanf("%d",&t);
while(t--)
{
flag=false;
num_u=num_i=0;
scanf("%s",str);
if(str[0]!='M' || str[1]==0)
{
printf("No\n");
continue;
}
for(i=1;str[i];i++)
if(str[i]=='I')
num_i++;
else if(str[i]=='U')
num_u++;
else
{
flag=true;
}
if(flag)
{
printf("No\n");
continue;
}
if(is_ok(num_i,num_u))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}