最小的特殊数字
描述
用全部N(N<=10)个0-9的数字组成一个“有效”整数(即没有前置0的整数),
求这些组成的数中能被K(0<K<10^10)整除的最小数字。
输入格式
输入分两行,第一行输入N, K,第二行输入N个数字。
输出格式
输出满足条件的最小的数(不含前置0),如果没有满足条件的数输出 -1。
输入样例
4 7
4 0 1 3
输出样例
1043
提示
413 % 7 = 0, 但是有前置0,所以满足条件的最小数是 1043 % 7 = 0。
此类题目需注意特殊情况,比如n=1时,如只输入一个0,答案只能是0。
注意long long
代码复现+优化(未OJ)
#include <iostream>
#include <cmath>
using namespace std;
bool check(int *everyNumberCnt, int &numbersCnt, int x) {
int everyNumberUse[10] = {0};//每个数字已用用的次数
while (x) {
int lastNum = x % 10;//最后一位数字
everyNumberUse[lastNum]++;
x /= 10;
}
//检查已用次数是否与可用次数相等
for (int i = 0; i < 10; ++i)
if (everyNumberCnt[i] != everyNumberUse[i])return false;
return true;
}
int main() {
int everyNumberCnt[10] = {0};//每个数字可用的次数
int numbersCnt, k;
cin >> numbersCnt >> k;
for (int i = 0; i < numbersCnt; ++i) {
int Anum;
cin >> Anum;
everyNumberCnt[Anum]++;
}
if (numbersCnt == 1) {
cout << 0 << endl;
return 0;
}
int start = 1000 / k;//无前置0
int maxi = pow(10, numbersCnt + 1) / k + 1;//输入的数字位数能组成最大的数数量级/k
for (int i = start; i < maxi; ++i) {
int res = i * k;//生成一个数
if (check(everyNumberCnt, numbersCnt, res)) {
cout << res << endl;
return 1;
}
}
cout << -1 << endl;
return 0;
}
原答案(AC)
#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
bool check(int numbers[],int numCnt,long long x){
int everycnt[10]={0};
for(int i=0;i<numCnt;i++){
everycnt[numbers[i]]++;
}
int use[10]={0};
while(x){
int anum=x%10;
use[anum]++;
x/=10;
}
for(int i=0;i<10;i++){
if(use[i]!=everycnt[i])return false;
}
return true;
}
int main()
{
int numbers[10];
int numCnt;
long long K;
cin>>numCnt>>K;
for(int i=0;i<numCnt;i++){
cin>>numbers[i];
}
if(numCnt==1){
cout<<0<<endl;
return 0;
}
// int x;
// cin>>x;
// cout<<check(numbers,numCnt,x);
int start=1000/K;
long long maxn=pow(10,numCnt+1)/K+1;
for(long long j=start;j<maxn;j++){
long long shu=j*K;
if(check(numbers,numCnt,shu)){
cout<<shu<<endl;
return 0;
}
}
cout<<-1<<endl;
return 0;
}