很久沒寫部落格了,過來水一下啦。
前兩題水題,就直接貼程式碼了。
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;
}