【杭电多校第七场】A + B = C

原题:

Given a,b,c, find an arbitrary set of x,y,z such that a*10^x+b*10^y=c*10^z and 0≤x,y,z≤10^6.

给你三个高精度数a、b、c,要求找出任意一组x、y、z满足a*10^x+b*10^y=c*10^z

首先需要发现一个性质

乘上10的幂会往数的最后面填上0,而不会对最前面的位造成影响

一开始我的思路是考虑三个数的个位,这种就很麻烦了

(听说能忽略前导零然后讨论,但我总觉得是假做法)

考虑前面位的话,就只有几种情况:

①a、b、c对齐

②a和b对齐,然后相加进一位,然后和c对齐

③a和c对齐,b在中间

④a加上b进一位和c对齐

⑤⑥同③④

(注意重要性质:加法最多只会进1,最多增加1位)

前两个可以a+b然后判断

后两个可以c-a然后判断

(这里的a、b、c都是指对齐过的)

所有情况都判断一下找到一组解就vans了

接下来就是喜闻乐见的码农时间

因为情况比较多,所以用工具函数,数组作为参数,以a[0]作为a的长度,这样是非常舒服的

一开始写的是二分,即a和c对齐后二分b左移的位数

但是又100组数据,1e6*log1e6*100肯定T了

实际上不用二分,直接减然后判断是比较简单的

另外,第一次写的时候左移是用函数里的参数控制的,这样写前两个还好,后四个情况再带上减法会及其麻烦

写到后期把减法加进去后代码直接崩溃了,前言不搭后语

最后额外开三个高精度数,写一个左移函数,用函数额外的一个参数表示高精度运算过后的结果放到哪里

这样写下来一气呵成,很顺利

所以说代码自动化和通用工具函数还是很有用的

(一开始写屎的锅就是因为中午没睡一脸蒙蔽=。=)

总结经验:
1.有时候不要贪图局部的代码方便

尤其是不要偷懒,为了想起来简单而放弃写通用函数

2.结构化程序设计(或者工具函数、代码自动化)带来的加成是惊人的

甚至可以为了这些放弃别的东西,比如代码复杂度,比如常数

3.敢于重构代码

又一个实例证明重构利大于弊

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 int a[3100000],b[3100000],c[3100000],d[3100000];
  8 int e[3100000],f[3100000],g[3100000];
  9 void clr(int x[]){
 10     for(int i=1;i<=x[0];++i)  x[i]=0;
 11     x[0]=0;
 12 }
 13 void rvs(int x[]){
 14     clr(d);
 15     d[0]=x[0];
 16     for(int i=1;i<=d[0];++i)  d[i]=x[i];
 17     for(int i=1;i<=d[0];++i)  x[i]=d[d[0]-i+1];
 18 }
 19 void rd(int x[]){
 20     clr(x);
 21     char ch=getchar();
 22     while(ch<'0'||ch>'9')  ch=getchar();
 23     while(ch>='0'&&ch<='9'){
 24         x[++x[0]]=ch-'0';
 25         ch=getchar();
 26     }
 27     rvs(x);
 28 }
 29 void cpy(int x[],int y[]){
 30     clr(y);
 31     y[0]=x[0];
 32     for(int i=1;i<=x[0];++i)  y[i]=x[i];
 33 }
 34 void lm(int x[],int y,int z[]){
 35     cpy(x,z);
 36     for(int i=z[0];i>=1;--i)  z[i+y]=z[i];
 37     for(int i=1;i<=y;++i)  z[i]=0;
 38     z[0]+=y;
 39 }
 40 void pls(int x[],int y[],int z[]){
 41     clr(z);
 42     z[0]=max(x[0],y[0]);
 43     for(int i=1;i<=x[0];++i)  z[i]+=x[i];
 44     for(int i=1;i<=y[0];++i)  z[i]+=y[i];
 45     for(int i=1;i<=z[0];++i)if(z[i]>=10){
 46         z[i+1]+=z[i]/10;
 47         z[i]%=10;
 48     }
 49     if(z[z[0]+1])  ++z[0];
 50 }
 51 void mns(int x[],int y[],int z[]){
 52     cpy(x,z);
 53     for(int i=1;i<=z[0];++i){
 54         z[i]-=y[i];
 55         if(z[i]<0){
 56             z[i]+=10;
 57             --z[i+1];
 58         }
 59     }
 60     while(!z[z[0]])  --z[0];
 61 }
 62 int cmp(int x[],int y[]){
 63     if(x[0]<y[0])  return -1;
 64     if(x[0]>y[0])  return 1;
 65     for(int i=x[0];i>=1;--i){
 66         if(x[i]<y[i])  return -1;
 67         if(x[i]>y[i])  return 1;
 68     }
 69     return 0;
 70 }
 71 void ot(int x,int y,int z){
 72     int mn=min(x,min(y,z));
 73     printf("%d %d %d
",x-mn,y-mn,z-mn);
 74 }
 75 int chck(int x[],int y[]){
 76     if(x[0]<y[0])  return -1;
 77     for(int i=y[0],j=x[0];i>=1;--i,--j)
 78         if(y[i]!=x[j])  return -1;
 79     for(int i=1;i<=y[0]-x[0];++i)
 80         if(x[i])  return -1;
 81     return x[0]-y[0];
 82 }
 83 void gogogo(){
 84     int mxl=max(a[0],max(b[0],c[0]));
 85     lm(a,mxl-a[0],e),lm(b,mxl-b[0],f),lm(c,mxl-c[0],g);
 86     pls(e,f,d);
 87     if(!cmp(d,g)){
 88         ot(mxl-a[0],mxl-b[0],mxl-c[0]);
 89         return ;
 90     }
 91     lm(c,mxl-c[0]+1,g);
 92     if(!cmp(d,g)){
 93         ot(mxl-a[0],mxl-b[0],mxl-c[0]+1);
 94         return ;
 95     }
 96     int tmx=max(a[0]+b[0],c[0])+b[0]-1;
 97     lm(a,tmx-a[0],e),lm(b,tmx-b[0],f),lm(c,tmx-c[0],g);
 98     if(cmp(g,e)==1){
 99         mns(g,e,d);
100         int tmp=chck(d,b);
101         if(tmp!=-1){
102             ot(tmx-a[0],tmp,tmx-c[0]);
103             return ;
104         }
105     }
106     if(cmp(g,f)==1){
107         mns(g,f,d);
108         int tmp=chck(d,a);
109         if(tmp!=-1){
110             ot(tmp,tmx-b[0],tmx-c[0]);
111             return ;
112         }
113     }
114     lm(c,tmx-c[0]+1,g);
115     if(cmp(g,e)==1){
116         mns(g,e,d);
117         int tmp=chck(d,b);
118         if(tmp!=-1){
119             ot(tmx-a[0],tmp,tmx-c[0]+1);
120             return ;
121         }
122     }
123     if(cmp(g,f)==1){
124         mns(g,f,d);
125         int tmp=chck(d,a);
126         if(tmp!=-1){
127             ot(tmp,tmx-b[0],tmx-c[0]+1);
128             return ;
129         }
130     }
131     printf("-1
");
132 }
133 void prvs(){
134     clr(a),clr(b),clr(c),clr(d);
135 }
136 int main(){
137     freopen("ddd.in","r",stdin);
138     a[0]=0,b[0]=0,c[0]=0,d[0]=0;
139     int T;  cin>>T;
140     while(T --> 0){
141         prvs();
142         rd(a),rd(b),rd(c);
143         gogogo();
144     }
145     return 0;
146 }
View Code
原文地址:https://www.cnblogs.com/cdcq/p/11340873.html