列表

详情


NC204897. 牛牛的呱数

描述

牛牛和小青蛙Froggy是好朋友。
牛牛有 n 种很大的数,每种数有无限个,牛牛可以从这些数中任选若干个(至少1个),并把它们拼接起来,拼接顺序任意,所有可以被这样拼接起来的数被成为“呱数”。
如果一个“呱数”还满足它是 p 的倍数,牛牛称它为“p-呱数”。
求长度最短的 “p-呱数” 的长度是多少。
若无解则输出 -1。

输入描述

第一行两个正整数 n,p 。
接写来 n 行,每行一个数字串。

输出描述

若无解则只输出 -1。
否则输出一个整数表示长度最短的 “p-呱数” 的长度。

示例1

输入:

3 11
114514
12345
18

输出:

8

说明:

最短的 “11-呱数” 为 11451418,长度为 8。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 22ms, 内存消耗: 1492K, 提交时间: 2020-04-26 18:43:59

#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int n, p;
char s[1000010];
int dp[210][210];
int main(){
	scanf("%d%d", &n, &p);
	memset(dp, 0x3f, sizeof(dp));
	for(int i = 1; i <= n; i++){
		scanf("%s", s+1);
		int len = strlen(s+1), val = 0, tmp = 1;
		for(int j = 1; j <= len; j++){
			val = (val*10+s[j]-'0')%p;
			tmp = (10*tmp)%p;
		}
		for(int j = 0; j < p; j++)
			dp[j][(j*tmp+val)%p] = min(dp[j][(j*tmp+val)%p], len);
	}
	for(int k = 0; k < p; k++)
		for(int i = 0; i < p; i++)
			for(int j = 0; j < p; j++)
				dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]);
	
	if(dp[0][0]==inf) printf("-1");
	else printf("%d", dp[0][0]);		
}

C++11(clang++ 3.9) 解法, 执行用时: 51ms, 内存消耗: 1628K, 提交时间: 2020-04-24 19:58:20

#include<bits/stdc++.h>
using namespace std;

int n,p,len=0;
char s[1000010];
long long dis[210][210],t[210][210];

void Pow(){
	for(int k=0;k<p;k++)
		for(int i=0;i<p;i++)
			for(int j=0;j<p;j++)
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}

int main(){
	scanf("%d %d",&n,&p);
	for(int i=0;i<p;i++) for(int j=0;j<p;j++) dis[i][j]=1e18;
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);len=strlen(s+1);
		long long t=1,tot=0;
		for(int j=len;j>=1;j--) (tot+=(s[j]-'0')*t%p)%=p,(t*=10)%=p;
		for(int j=0;j<p;j++) dis[j][(j*t+tot)%p]=min(dis[j][(j*t+tot)%p],1ll*len);
	}
	Pow();
	if(dis[0][0]==1e18) printf("-1");
	else printf("%lld\n",dis[0][0]);
}

上一题