西行寺幽幽子
题目
题目描述
在幻想乡,西行寺幽幽子是以贪吃闻名的亡灵。不过幽幽子可不是只会吃,至少她还管理着亡 灵界。话说在幽幽子居住的白玉楼有一颗常年不开花的樱树——西行妖。幽幽子决定去收集人 间的春度,聚集起来让西行妖开花。很快,作为幽幽子家园艺师的魂魄妖梦收集到了 M 个单位 的春度。并且在这段时间里,幽幽子计算出要让西行妖开出一朵花需要 N 个单位的春度。 现在幽幽子想要知道,使用所有的春度,能够让西行妖开出多少朵花。
输入格式
第 1 行:一个正整数 M 第 2 行:一个正整数 N N,M 的位数不超过L,L 的范围在题目后面给出
输出格式
第 1 行:一个整数ans,表示能开出花的朵数 输入样例 73861758 12471
输出样例
5922
数据范围
对于 60%的数据:L <= 2,000 且 ans <= 2,000 对于 100%的数据:L <= 20,000 且 ans <= 2,000,000,000
思路一
直接模拟
O(N^2)
code(还没调出来)
#include<bits/stdc++.h>
using namespace std;
const int N=21010;
char s1[N],s2[N];
int a[N],b[N],c[N],d[N];
int la,lb,lc,ld,sum;
bool BigJudge(){
if(lc<lb)return false;
if(lc>lb)return true;
for(int i=lb;i>=1;i--){
if(c[i]>b[i])return true;
if(c[i]<b[i])return false;
}
return true;
}
void AddD(int key){
ld=lb;
for(int i=1;i<=lb;i++)
d[i]=b[i]*key;
d[ld+1]=0;
for(int i=1;i<=lb;i++){
d[i+1]+=d[i]/10;
d[i]=d[i]%10;
}
if(d[ld+1])ld++;
return;
}
bool TimesJudge(int key){
AddD(key);
if(lc<ld)return false;
if(lc>ld)return true;
for(int i=ld;i>=1;i--){
if(c[i]>d[i])return true;
if(c[i]<d[i])return false;
}
return true;
}
void Work(int key){
AddD(key);
int Nlc=0;
for(int i=1;i<=lc;i++){
c[i]-=d[i];
if(c[i-1]<0)c[i]--,c[i-1]+=10;
if(c[i]>0)Nlc=i;
}
lc=Nlc;
return;
}
void AddC(){
lc++;
int last=0,rcd=0;
for(int i=1;i<=lc;i++){
rcd=c[i];
c[i]=last;
last=rcd;
}
return;
}
int main(){
//freopen("spring.in","r",stdin);
//freopen("spring.out","w",stdout);
cin>>s1+1;
cin>>s2+1;
la=strlen(s1+1);
lb=strlen(s2+1);
for(int i=1;i<=la;i++)
a[i]=s1[la-i+1]-'0';
for(int i=1;i<=lb;i++)
b[i]=s2[lb-i+1]-'0';
for(int i=la;i>=1;i--){
AddC();
c[1]=a[i];
if(BigJudge()){
int l=1,r=9,ans=-1;
while(l<=r){
int mid=(l+r)>>1;
if(TimesJudge(mid)){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
sum*=10;
sum+=ans;
Work(ans);
}
else{
sum*=10;
if(lc==1 && c[1]==0)
lc--;
}
}
printf("%d",sum);
return 0;
}
思路二
O(n log n)
由于ans范围很小
可以二分枚举ans
乘回去验证
单精对高精
#include<bits/stdc++.h>
using namespace std;
const int N=2e4+10;
char a[N],b[N];
long long ans,s1[N],s2[N],c[N],la,lb,lc;
void work(long long key){
for(int i=lc;i>=1;i--)c[i]=0;
lc=lb;
for(int i=1;i<=lb;i++)
c[i]=key*s2[i];
for(int i=1;i<lc;i++){
c[i+1]+=c[i]/10;
c[i]=c[i]%10;
}
while(1){
if(c[lc]>=10){
c[lc+1]=c[lc]/10;
c[lc]=c[lc]%10;
}
else break;
lc++;
}
return;
}
bool check(){
if(lc<la)return true;
if(lc>la)return false;
for(int i=1;i<=lc;i++){
if(c[i]<s1[i])return true;
if(c[i]>s1[i])return false;
}
return true;
}
int main(){
cin>>a+1>>b+1;
la=strlen(a+1);
lb=strlen(b+1);
for(int i=la;i>=1;i--)
s1[i]=a[la-i+1]-'0';
for(int i=lb;i>=1;i--)
s2[i]=b[lb-i+1]-'0';
long long l=0,r=2e9;
while(l<=r){
long long mid=(l+r)>>1;
work(mid);
if(check())ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d",ans);
return 0;
}