HDU 5920

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5920

题意:给出长度为1000的10进制数n,让你用小于50个回文数来组成n。

思路:我们可以取当前串的前面一半,例如 93840 ,取938 ,然后另这串减1 ,(减1是为了对称后比原来串小)得937,然后再对称得到 93739 ,

用原串减去当前串得到一个位数减少一半的新串 111,然后再采取这样的操作,但当那个数小于20时就会进入死循环,所以当它小于20时就特判下。

我的代码在当a[1]=1时,就用n-1个9来构成一个回文串,这样可以好一点确定所选定回文串的位数。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
int a[2005],b[55][2005],p[55],c[2005];
char s[2005];
int n,k;
void fun()
{
    k++;
    if(a[1]==1)
    {
        p[k]=n-1;
        for(int i=1;i<n;i++)
            b[k][i]=9;
        for(int i=n;i>1;i--)
            a[i]-=9;
        for(int i=n;i>1;i--)
        {
            if(a[i]<0)
            {
                a[i]+=10;
                a[i-1]--;
            }
        }
        if(a[1]==0)
        {
            int y;
            for(int i=1;i<=n;i++)
            {
                if(a[i]>0)
                {
                    y=i;
                    break;
                }
            }
            for(int i=1,j=y;j<=n;i++,j++)
                a[i]=a[j];
            n=n-y+1;
        }
        return;
    }
    int v=0;
    if(n%2)
        v=1;
    int x=n/2+v;
    for(int i=1;i<x;i++)
        c[i]=a[i];
    c[x]=a[x]-1;
    if(c[x]<0)
    {
        for(int i=x;i>1;i--)
        {
            if(c[i]<0)
            {
                c[i]+=10;
                c[i-1]--;
            }
            else
                break;
        }
    }
    for(int i=x+1,j=x-v;i<=n;i++,j--)
        c[i]=c[j];
    p[k]=n;
    for(int i=1;i<=n;i++)
    {
        a[i]-=c[i];
        b[k][i]=c[i];
    }
    for(int i=n;i>1;i--)
    {
        if(a[i]<0)
        {
            a[i]+=10;
            a[i-1]--;
        }
    }
    int y;
    for(int i=1;i<=n;i++)
    {
        if(a[i]>0)
        {
            y=i;
            break;
        }
    }
    for(int i=1,j=y;j<=n;i++,j++)
        a[i]=a[j];
    n=n-y+1;
}
int main()
{
    int t,u=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        n=strlen(s);
        for(int i=0;i<n;i++)
            a[i+1]=s[i]-'0';
        k=0;
        while(1)
        {
            if(n==1)
            {
                k++;
                p[k]=1;
                b[k][1]=a[1];
                break;
            }
            if(n==2)
            {
                int sum=a[1]*10+a[2];
                if(sum<19)
                {
                    p[++k]=1;
                    b[k][1]=9;
                    p[++k]=1;
                    b[k][1]=sum-9;
                    break;
                }
                else if(sum==19)
                {
                    p[++k]=2;
                    b[k][1]=1;
                    b[k][2]=1;
                    p[++k]=1;
                    b[k][1]=8;
                    break;
                }
            }
            fun();
        }
        printf("Case #%d:
",++u);
        printf("%d
",k);
        for(int i=1;i<=k;i++)
        {
            for(int j=1;j<=p[i];j++)
                 printf("%d",b[i][j]);
            printf("
");
        }
    }
}
原文地址:https://www.cnblogs.com/zcb123456789/p/12526102.html