POJ 1117

题意:给出一个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 }

你可能感兴趣的:(poj)