1 条题解
-
0
自动搬运
来自洛谷,原作者为

唐一文
搬运于
2025-08-24 21:42:10,当前版本为作者最后更新于2020-01-30 15:24:36,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
前言
题解区里的方法都太深奥了,蒟蒻看不懂
思路 && Code
受到UVA1189的启发,我们可以先求出串,再算出。
认为数据一定很水的我立马打了个,开了个准备水过去:#include<bits/stdc++.h> using namespace std; int n; long long minn=LONG_LONG_MAX; void dfs(long long ans,int k){ if(k==20){//超出long long范围 return ; } if(ans>minn){//剪枝 return ; } if(ans%n==0){ minn=min(minn,ans);//求最小值 return ; } dfs(10*ans,k+1); dfs(10*ans+1,k+1); } int main(){ cin>>n; dfs(1,1); cout<<minn/n<<" "<<minn; return 0; }然而,是这样的:
还是老老实实打高精度吧把高精度模板一套:
#include<bits/stdc++.h> using namespace std; int n; inline int mod(string a1){//求余数 register int i; int b=0,len=a1.size(); for(i=0;i<len;++i){ b=((b<<1)+(b<<3)+(a1[i]^48))%n; } return b; } inline string chu(string a1){//高精度除法 register int i; int s[10001],b=0,len=a1.size(); for(i=0;i<len;++i){ s[i]=((b<<1)+(b<<3)+(a1[i]^48))/n; b=((b<<1)+(b<<3)+(a1[i]^48))%n; } i=0; while(!s[i] && i<len){ ++i; } a1=""; while(i<len){ a1+=s[i]+'0'; ++i; } return a1; } string minn; inline bool pd(string x){//判断是否超过已找到的最小值 int lx=x.size(),ly=minn.size(); if(lx<ly){ return false; } if(lx>ly){ return true; } register int i; for(i=0;i<lx;++i){ if(x[i]<minn[i]){ return false; } else if(x[i]>minn[i]){ return true; } } return false; } void dfs(string ans){ if(pd(ans)){ return ; } if(!mod(ans)){ minn=ans; return ; } dfs(ans+"0"); dfs(ans+"1"); } int main(){ register int i; scanf("%d",&n); for(i=1;i<37;++i){//1~9999中答案的最大值 /* 不难发现,n为9的倍数时,答案总是很大 当n=9999时最大 那么n=9*1111 因为9|111111111 有9个1 而1111有4个1 又因为4和9互质 所以minn=111...111(4*9=36个1) */ minn+="1"; } dfs("1"); cout<<chu(minn)<<" "<<minn; return 0; }内心想法:我终于又水过了一道
水蓝题
还会超时让我们重新看一下题目:
给出一个数,你需要给出一个最小的数,使得与的乘积只含有和在学搜索时,求最小的答案一般用更快
那么这题不就可以用了吗因为要求最小的,所以先插入比先插入更好
找到的满足条件的第个数就是把改成:
#include<bits/stdc++.h> using namespace std; int n; inline int mod(string a1){ register int i; int b=0,len=a1.size(); for(i=0;i<len;++i){ b=((b<<1)+(b<<3)+(a1[i]^48))%n; } return b; } inline string chu(string a1){ register int i,j; int s[10001],b=0,len=a1.size(); for(i=0;i<len;++i){ s[i]=((b<<1)+(b<<3)+(a1[i]^48))/n; b=((b<<1)+(b<<3)+(a1[i]^48))%n; } i=0; while(!s[i] && i<len){ ++i; } a1=""; while(i<len){ a1+=s[i]+'0'; ++i; } return a1; } string p; queue<string>q; int main(){ register int i; scanf("%d",&n); //以下代码为改动了一点的bfs模板 p="1"; q.push(p); while(!q.empty()){ p=q.front(); q.pop(); if(!mod(p)){ cout<<chu(p)<<" "<<p; return 0; } q.push(p+"0"); q.push(p+"1"); } return 0; }这次总能过了吧
是什么鬼让我们手动模拟一下样例: | | | | :----------: | :----------: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 可以发现,有些数模同余
根据同余的性质可得,它们乘上同一个数后模也同余
因为要求最小的数,所以只要取这些数中最小的那一个数
用一个数组即可实现因为我们是从小到大搜索的
所以第一个出现的数就是最小的那一个AC Code
#include<bits/stdc++.h> using namespace std; int n; inline int mod(string a1){ register int i; int b=0,len=a1.size(); for(i=0;i<len;++i){ b=((b<<1)+(b<<3)+(a1[i]^48))%n; } return b; } inline string chu(string a1){ register int i,j; int s[10001],b=0,len=a1.size(); for(i=0;i<len;++i){ s[i]=((b<<1)+(b<<3)+(a1[i]^48))/n; b=((b<<1)+(b<<3)+(a1[i]^48))%n; } i=0; while(!s[i] && i<len){ ++i; } a1=""; while(i<len){ a1+=s[i]+'0'; ++i; } return a1; } string p; bool v[10005];//判断是否重复出现余数 queue<string>q; int main(){ register int i; scanf("%d",&n); p="1"; q.push(p); while(!q.empty()){ p=q.front(); q.pop(); if(!mod(p)){ cout<<chu(p)<<" "<<p; return 0; } if(!v[mod(p+"0")]){//如果没有出现过这个余数 v[mod(p+"0")]=true;//这个数为最小的那一个,这个余数现在出现了,标记为true q.push(p+"0"); } if(!v[mod(p+"1")]){//同上 v[mod(p+"1")]=true; q.push(p+"1"); } } return 0; }(° - °)ノ✿ 完结撒花~
- 1
信息
- ID
- 1911
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者