很久没写博客了,过来水一下啦。
前两题水题,就直接贴代码了。
A题,题目地址:Good Number
AC代码:
#include<iostream>
#include<cstring>
using namespace std;
int k;
int visi[10];
int solve(int p)
{
memset(visi,0,sizeof(visi));
while(p)
{
visi[p%10]=1;
p/=10;
}
for(int i=0;i<=k;i++)
if(!visi[i]) return 0;
return 1;
}
int main()
{
int n,i;
int s,ans;
while(cin>>n>>k)
{
ans=0;
for(i=0; i<n; i++)
{
cin>>s;
if(solve(s))
ans++;
}
cout<<ans<<endl;
}
return 0;
}
B题,题目地址:The Fibonacci Segment
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int dp[100005];
int a[100005];
int main()
{
int n,i;
int ma;
while(cin>>n)
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
if(n==1)
{
puts("1");
continue;
}
memset(dp,0,sizeof(dp));
ma=0;
for(i=3;i<=n;i++)
{
if(a[i]==a[i-1]+a[i-2])
{
dp[i]=dp[i-1]+1;
ma=max(dp[i],ma);
}
}
cout<<ma+2<<endl;
}
return 0;
}
C题
题目大意:给你一个串s,然后用串构造一个矩阵a,a[i][j]=s[i]*s[j]。给你一个k,问存多少这样的子矩阵,使得每一个子矩阵矩阵内a[i][j]的和刚好为k。
解题思路:开始看得真感觉无厘头,但是当我把5*5的矩阵画出来之后就发现了规律。比如以a[2][2]为起点长为3宽为2的矩阵和直接为(p[2]+p[3]+p[4])*(p[2]+p[3]),这里的p对应上面的串s,p[i]=s[i]-'0'。根据这个把每一行可以产生的和都统计出来,然后把和的个数记录出来,列实际上和行是一样的。然后sum[i]*sum[a/i]就表示的是和为a的个数。不过前提是a>0。如果a==0怎么办呢,这时候就需要特判了,把sum[0]统计出来,然后2*sum[0]*sum[i](i从1~dp[len])+sum[0]*sum[0]
题目地址:A. Matrix
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char s[4005];
__int64 sum[40005],dp[4005];
int main()
{
int len,i,j;
__int64 a,res,t;
while(cin>>a>>s)
{
res=0;
len=strlen(s);
dp[0]=0;
memset(sum,0,sizeof(sum));
//sum[i]记录连续行的和或连续列的和的个数
//sum[i]*sum[a/i]就是行列形成矩阵且矩阵的和为a的个数
for(i=1;i<=len;i++)
{
dp[i]=dp[i-1]+(s[i-1]-'0');
for(j=0;j<i;j++)
sum[dp[i]-dp[j]]++;
}
if(a==0)
{
for(i=1;i<=dp[len];i++)
res+=2*sum[0]*sum[i];
res+=sum[0]*sum[0];//0单独处理,sum[0]只处理一次
}
else
{
for(i=1;i<=dp[len];i++)
{
if(a%i==0&&a/i<=dp[len])
res+=sum[i]*sum[a/i];
}
}
printf("%I64d\n",res);
}
return 0;
}