数字河(模拟)

来源:互联网 发布:spark 提交python脚本 编辑:程序博客网 时间:2024/06/11 18:54



描述
数字河中的一个数n 的后继数是n 加上其每位数字的和。例如,12345的后继数是12360,因为12345+1+2+3+4+5=12360。
如果数字河的第一个数为k,我们就称此数字河为river k。

例如,river 480 代表序列{480, 492, 507, 519, ...},river 483 代表序列{483, 498, 519, ...}。
当两个数字河有相同的元素时,我们称这两个数字河在此元素处相遇。例如,river 480 和river 483 在元素519处相遇。所有数字河都会和river 1, river 3 或river 9 相遇。编程计算给定的数字河最先与以上三条河流中的哪一条相遇,在何元素处相遇?


输入
输入文件包括多组测试用例,每个测试用例占一行,以“0”标志文件结束,
该行无需处理。
每行给定一个整数 n ,(1<=n<=16384) ,即river n。
 
输出
对于每个测试用例输出两行,第一行为测试用例号,第二行输出“first meets river x at y”。
其中,y表示river n 最先遇到的river x中的最小元素值(x = 1,3,9)。




题解

emmmm这个题用数组先把三条河所有的变化情况存下来,然后开始用while开始变化n,每变一次和三条数字河匹配一次,(注意不用从头匹配,匹配时让三个数组各模拟一个尾指针往后扫,扫到a[i]>n时停止,n变化后接着上次的尾指针继续往后扫就可以辣~)直到碰到最先匹配成功的就输出


!!!这个貌似可以n变化的时候可以每变一次二分匹配一下三条河,但是可能也不一定很快,,而且我觉得时间复杂度不是很稳定诶。。



#include<cstdio>
#include<iostream>
using namespace std;

int a1[10010],a3[10010],a9[10010];

int main()
{
 int n,a,t,sum,i=1;
 a=1,a1[1]=1;
 while(a<=16384)
 {
  t=a,sum=0;
  while(t)
  {
   sum+=t%10;
   t/=10;
  }
  a+=sum;
  i++;
  a1[i]=a;
 }
  a=3,a3[1]=3;
 while(a<=16384)
 {
  t=a,sum=0;
  while(t)
  {
   sum+=t%10;
   t/=10;
  }
  a+=sum;
  i++;
  a3[i]=a;
 }
  a=9,a9[1]=9;
 while(a<=16384)
 {
  t=a,sum=0;
  while(t)
  {
   sum+=t%10;
   t/=10;
  }
  a+=sum;
  i++;
  a9[i]=a;
 }
 int cnt=1;
 while(cin>>n&&n!=0)
 {
  cout<<"Case #"<<cnt<<endl;
  cnt++;
  int i1=1,i3=1,i9=1;
  while(1)
  {
   
    while(a1[i1]<n)
    {
   i1++;
    }
    if(a1[i1]==n)
    {
       cout<<"first meets river 1 at "<<n<<endl;
     break; 
    }
    while(a3[i3]<n)
    {
   i3++;
    }
    if(a3[i3]==n)
    {
       cout<<"first meets river 3 at "<<n<<endl;
     break; 
    }
    while(a9[i9]<n)
    {
   i9++;
    }
    if(a9[i9]==n)
    {
       cout<<"first meets river 9 at "<<n<<endl;
     break; 
    }
   
     t=n;
     while(t)
     {
     n+=t%10;
     t/=10;
     } 
  }

 }

 return 0;
}