Step1 Problem:
n 个数 和 k,n 个数 分别 a[1] … a[n].
连接两个数如:
connection(x, y) = xy.
connection(45, 112) = 45112.
让你求 connection(a[i], a[j])%k == 0 的个数 (i != j)
数据范围:
1 <= n <= 2e5,
2 <= k <= 1e9,
1 <= a[i] <= 1e9.
Examples
Input
6 11
45 1 10 12 11 7
Output
7
Input
4 2
2 78 4 10
Output
12
Input
5 2
3 7 19 3 3
Output
0
connection(45, 112) = 45112.
45112 = 451000+112;
(a[i]%kmul%k + a[j]%k)%k == 0
时间复杂度 O(n10log(1e9));
代码实现:
//时间复杂度为O(n).
#include<iostream>
#include<map>
#define maxn 200020
using namespace std;
int a[maxn],b[11],c[maxn];
map<int,int>m[11];
int main()
{
int n,k,i,j,t;
cin>>n>>k;
b[0]=1;
for(i=1;i<11;i++)
b[i]=(b[i-1]*10)%k;
for(i=0;i<n;i++)
{
cin>>a[i];
t=a[i];
c[i]=0;
while(t!=0)
{
t=t/10;
c[i]++;
}
a[i]=a[i]%k;
for(j=1;j<11;j++)
m[j][(long long)a[i]*b[j]%k]++;
}
long long re=0;
for(i=0;i<n;i++)
{
re+=m[c[i]][(k-a[i])%k];
if(a[i]==0)
re--;
if((long long)a[i]*b[c[i]]%k==k-a[i])
re--;
}
cout<<re<<endl;
}
超时代码:
//时间复杂度为O(n*n).
#include <iostream>
#define maxn 200020
using namespace std;
int a[3][maxn];
int digit(int n)
{
int t=1;
while(n!=0)
{
n=n/10;
t=t*10;
}
return t;
}
int main()
{
int n,k,i,j;
cin>>n>>k;
for(i=0; i<n; i++)
{
cin>>a[0][i];
a[1][i]=a[0][i]%k;
a[2][i]=digit(a[0][i]);
}
long long re=0;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(j==i)
continue;
if((a[1][i]*(a[2][j]%k)+a[1][j])%k==0)
re++;
}
}
cout<<re<<endl;
return 0;
}
知识补充:
精确到毫秒时间:
#include<stdio.h>
#include <stdlib.h>//用到rand()函数
#include<time.h> //用到clock()函数
int main() {
int begintime,endtime;
int i = 0;
int a[1002];
begintime=clock(); //计时开始
for( i = 1; i <= 1000; i++){//要计时的程序
a[i] = rand()%200-100;//产生-100到+100之间的随机数
printf(" %d",a[i]);
}
endtime = clock(); //计时结束
printf("\n\nRunning Time:%dms\n", endtime-begintime);
return 0;
}