题意:给出一个n,求所有的x+y=n且y是x长度仅差1的子序列。
题解:分情况讨论,设y是x剔除第i位得到的数,
1)若i>lenth(n)/2,
y=x/10^i*10^(i-1)+x%10^(i-1)
=x/10^i*10(i-1)+x-x/10^(i-1)*10^(i-1)
=x-(x/10^(i-1)-x/10^i)*10^(i-1)
x+y=2x-(x/10^(i-1)-x/10^i)*10^(i-1)=n
设T=(x/10^(i-1)-x/10^i)
2x-T*10^(i-1)=n
x=(n+T*10^(i-1))/2
x,n,T均为整数且i>1,所以n非偶数直接返回,其他情况则枚举T直到x大于n,共需枚举约n/(10^(i-1))次。
2)其他情况
x+y=2x-(x/10^(i-1)-x/10^i)*10^(i-1)
其中x/10^i=(x-x%10^i)/10^i
所以原式=(11x-(x%10^i-x%10^(i-1)*10))/10=n
令M=(x%10^i-x%10^(i-1)*10
x=(10n+M)/11
同样,n,m,x均为整数,且m的范围是[-10^i,10^i],枚举所有使x有整数解的m。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef long long LL; 6 LL po[15]; 7 struct Data 8 { 9 LL x,y; 10 bool operator<(const Data &ne)const 11 { 12 return x<ne.x; 13 } 14 }ans[10000]; 15 int top; 16 LL remove(LL x,int i) 17 { 18 return x/po[i]*po[i-1]+x%po[i-1]; 19 } 20 void solve1(int i,LL n) 21 { 22 LL left=-po[i],right=po[i],m=11-(10*n)%11,x; 23 for(LL mm=m;mm>=left;mm-=11) 24 { 25 x=(10*n+mm)/11; 26 if(x<=0ll) 27 break; 28 LL y=remove(x,i); 29 if(x+y==n) 30 { 31 ans[top].x=x; 32 ans[top++].y=y; 33 } 34 } 35 for(LL mm=m+11;mm<=right;mm+=11) 36 { 37 x=(10*n+mm)/11; 38 if(x>=n) 39 break; 40 LL y=remove(x,i); 41 if(x+y==n) 42 { 43 ans[top].x=x; 44 ans[top++].y=y; 45 } 46 } 47 } 48 void solve2(int i,LL n) 49 { 50 if(n%2!=0) 51 return; 52 LL ad=po[i-1]/2; 53 for(LL x=n/2+ad;x<=n;x+=ad) 54 { 55 LL y=remove(x,i); 56 if(x+y==n) 57 { 58 ans[top].x=x; 59 ans[top++].y=y; 60 } 61 } 62 } 63 int main() 64 { 65 LL n; 66 po[0]=1; 67 for(int i=1;i<=10;i++) 68 po[i]=po[i-1]*10ll; 69 while(scanf("%lld",&n)!=EOF) 70 { 71 top=0; 72 int len; 73 for(len=1;len<=10;len++) 74 if(n<po[len]) 75 break; 76 for(int i=1;i<=len/2;i++) 77 solve1(i,n); 78 for(int i=len/2+1;i<=len;i++) 79 solve2(i,n); 80 if(top==0) 81 { 82 printf("0\n"); 83 continue; 84 } 85 sort(ans,ans+top); 86 int num=0; 87 for(int i=1;i<top;i++) 88 { 89 if(ans[i].x!=ans[num].x) 90 ans[++num]=ans[i]; 91 } 92 num++; 93 printf("%d\n",num); 94 for(int i=0,j,k;i<num;i++) 95 { 96 for(j=1;j<=10;j++) 97 if(ans[i].x<po[j]) 98 break; 99 for(k=1;k<=10;k++) 100 if(ans[i].y<po[k]) 101 break; 102 printf("%lld + ",ans[i].x); 103 k++; 104 while(k<j) 105 printf("0"),k++; 106 printf("%lld = %lld\n",ans[i].y,n); 107 } 108 } 109 return 0; 110 }