题目传送门
题意: 给你n个数,一个k,对于i,j(i!=j),把i和j拼接起来,问有多少对i ,j拼接之后,能被k整除。
思路1 对于每个数,我们把它的位数和模k之后的结果存起来,之后枚举n个数,再枚举,如果后面接一个1位数,2位数、3位数…统计结果就可以,注意减去自身拼接也可以的情况。
思路2 和思路1差不多,我们可以把一个数如果后面接1个1位数,2位数,三位数…的时候对k取模的值存下来,最后枚举n个数统计结果。
思路1代码 卡边缘过的,建议不用ll就不用,很费时间。
#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int unsigned long long
#define vi vector<int>
#define mii map<int,int>
#define pii pair<int,int>
#define ull unsigned long long
#define pqi priority_queue<int>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=3e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-6;
int a[N];
signed main()
{
int n,k;
n=read();k=read();
map<pii,int>ma;ma.clear();
for(int i=1;i<=n;i++)
{
a[i]=read();
int t=a[i]%k;
int j=a[i];
int cnt=0;
while(j)
{
j/=10;
cnt++;
}
ma[{cnt,t}]++;
}
int res=0;
for(int i=1;i<=n;i++)
{
int t=a[i];
int m=t%k;
int x=a[i];
int cnt=0;
while(x)
{
x/=10;
cnt++;
}
for(int j=1;j<=10;j++)
{
t*=10;
int tmp=t%k;
if(tmp==0)
res+=ma[{j,0}];
else
res+=ma[{j,k-tmp}];
}
int q=a[i];
while(cnt--)
{
q*=10;
q%=k;
}
if((q%k+a[i]%k)%k==0)
res--;
}
cout<<res<<endl;
}