C. Palindrome Basis
先将所有回文整数预处理出来,然后可看作完全背包。
f[j]
表示组成n的方案数
状态转移方程: f[j]=(f[j]+f[j-a[i]])%mod;
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const int N=4005;
int a[N],f[N],cnt;
int check(int x)
{
int b[10]={0},k=0;
while(x)
{
b[++k]=x%10;x/=10;
}
int i=1,j=k;
while(i<=j)
{
if(b[i]==b[j])
i++,j--;
else
return 0;
}
return 1;
}
int main()
{
for(int i=1;i<=4000;i++)
if(check(i))
a[++cnt]=i;
/*for(int i=1;i<=30;i++)
cout<<a[i]<<" ";
cout<<endl;*/
f[0]=1;
for(int i=1;i<=cnt;i++)
{
for(int j=a[i];j<=4000;j++)
{
f[j]=(f[j]+f[j-a[i]])%mod;
}
}
int t;cin>>t;
while(t--)
{
int n;cin>>n;
cout<<f[n]<<endl;
}
return 0;
}
D. Lost Arithmetic Progression
这题难度估计在1800以上了。
思路倒是看明白了,但难点应该在于多种情况的讨论,不能缺失。
本题一篇很好的博客
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod =1e9+7;
ll b,q,y,c,r,z;
int main()
{
int t;cin>>t;
while (t--)
{
scanf("%lld%lld%lld", &b, &q, &y);
scanf("%lld%lld%lld", &c, &r, &z);
ll bb=b+(y-1)*q, cc=c+(z - 1)*r;
//情况不存在的
if (b>c||(r%q)||((c-b)%q)||(bb<cc)||(c>bb)||(b>cc))
{
puts("0");
continue;
}
//无穷多个
if(b+r>c||(bb<cc+r))
{
puts("-1");
continue
}
ll res=0;
//数组A和B的最大公因数为C
for (ll i=1; i<=r/i; i++)
{
if(r%i)
continue;
ll t=i;
if (t*q /__gcd(t,q)==r) {
(res +=(r/t)*(r/t)%mod)%=mod;
}
if (i*i==r)
continue;
t=r/i;
if (t*q/__gcd(t,q)==r)
(res+=(r/t)*(r/t)%mod)%=mod;
}
printf("%lld\n", res);
}
return 0;
}