HDOJ-1271 换个思维就简单多了...

10 篇文章 0 订阅


     老早就尝试过这题..结果枚举方式不是很简洁...写起来各种蛋疼..昨晚听了惊奇哥的讲解就果断水了...

     设B=Bn,Bn-1,...B2,B1   枚举是再哪个位置插入了个位数k...比如枚举是第i位后面插入了个位数k..那么得到的

                          N=11*(Bn,Bn-1,...Bk+1)*(10^(i+1))+k*(10^i)+2*(Bk-1..B2,B1)

     应该不难理解吧...题目是给出了N...那么就反过来推了..看我程序吧..注意的就是一些情况的处理..如:

                         推出的中间数必须是个位数(有可能得到10..那么显然这个数是要不得的.)..

                         末尾的(Bk-1...B2,B1)不一定就是(Nk-1...N2,N1)/2阿..有可能是(1,Nk...N2,N1)/2...就如同后缀为2的..可能是1+1=2的2..也可能是6+6=12的2..

                         要排除10=05+5的这种错误情况..就是前缀和中间个位数不能同时为0..

                         最后..输出的时候让相同的数只输出一个...

     仔细想想..其实本题思路也不难想到了..思维应该更加灵活阿...

Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int N,B,k,x,y,i,m,ans[1000],num; 
int main()
{
     //  freopen("input.txt","r",stdin);
    //   freopen("output.txt","w",stdout); 
       while (~scanf("%d",&N))
    //   for (N=9000;N<=10000;N++)
       {
             if (!N) break;
             num=0; 
             y=N/11; x=N%11;
             if (x<10) ans[++num]=y*10+x; 
             i=10;
             if (N%2!=1)
             while (i<=N)
             {
                   x=(N%i)/2;
                   m=N/i;
                   y=m/11; 
                   k=m%11; 
                   if (k<10)
                   {
                         k=y*(i*10)+k*i+x;
                         ans[++num]=k;
                   }
                   x=(N%i+i)/2; 
                   k=m%11-1;
                   if (k>=0 && (y || k))
                   {
                         k=y*(i*10)+k*i+x;
                         ans[++num]=k;
                   }
                   i*=10;
             } 
            // printf("%d: ",N);
             if (!num) printf("No solution.\n");
             else 
             {
                   sort(ans+1,ans+1+num);
                   printf("%d",ans[1]);
                   for (i=2;i<=num;i++) 
                     if (ans[i]!=ans[i-1]) printf(" %d",ans[i]);
                   printf("\n");
             }
       }
       return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值