HDU 4294 or POJ 2283

来源:互联网 发布:数据,模型与决策 编辑:程序博客网 时间:2024/05/18 20:06

题目描述:给你n,k,则求出n的正整数倍数,使得这个数字在k进制下表示的时候需要的不同数字最小

首先明确最多的不同数字需要2种,证明如下

a,aa,aaa,aaaa,......找出n个连续的,那么中间至少有两个mod n的值是相等的,那么这两个数字相减,得到aaa...000肯定能被n整除

直接暴力搜索每一种情况

//至多两个数字就可以拼出任何数的倍数//给你n,k,则求出n的正整数倍数,使得这个数字在k进制下表示的时候需要的不同数字最小#include<cstdio>#include<cstring>#include<queue>using namespace std;const int N=10002;int n,c,k,l,l1;int pre[N],res[N],step[N],num[2];char ans[N],re[N];bool bfs()    //判断c个数能否组成n的倍数{queue<int> Q;int i,p,q;memset(step,0,sizeof(step));for(i=0;i<c;i++){int y=num[i]%n;if(num[i]==0||step[y]){continue;}step[y]=1;pre[y]=-1;res[y]=num[i];Q.push(y);}while(!Q.empty()){p=Q.front();Q.pop();if(p==0){return true;}if(l&&step[p]>l){return false;}for(i=0;i<c;i++){q=(p*k+num[i])%n;if(!step[q]){step[q]=step[p]+1;pre[q]=p;res[q]=num[i];Q.push(q);}}}return false;}void solve(int i){if(pre[i]!=-1){solve(pre[i]);}re[l1++]=res[i]+'0';}bool judge()  //比较大小{int i;if(!l||l1<l){return true;}if(l1>l){return false;}for(i=0;i<l;i++){if(ans[i]<re[i]){return false;}if(ans[i]>re[i]){return true;}}return false;}int main(){int i,j;while(~scanf("%d%d",&n,&k)){l=0;bool flag=false;for(i=1;i<k;i++){num[0]=i;c=1;if(bfs()){flag=true;l1=0;solve(0);if(judge()){l=l1;memcpy(ans,re,sizeof(ans));}}}if(!flag){for(i=0;i<k;i++){for(j=i+1;j<k;j++){num[0]=i;num[1]=j;c=2;if(bfs()){l1=0;solve(0);if(judge()){l=l1;memcpy(ans,re,sizeof(ans));}}}}}for(i=0;i<l;i++){printf("%c",ans[i]);}putchar(10);}return 0;}