北大ACM poj1016

/*举个例子来说明:
一个数5553141:他包含了2个1,1个3,1个4,3个5;
那么和起来写:21131435就是5553141的Inventory 数;
然后题目要求,给出一个数n( 最多80位),他可以被归到如下四类:
1)n is self-inventorying(n用给出那个数代,下同) 
即对给出的数,求出他的Inventory 数,如果是本身,则输出该行;
例如:31123314的Inventory数仍然是31123314,输出: 31123314 is self-inventorying 
2) n is self-inventorying after j steps  
对一个数求他的Inventory 数,然后再对他的Inventory数继续求,如实我们可以得到一个序列:n[0]->n[1]->n[2]…n[j]…. 如此往复,当1<=j<=15时。如果n[j]的Inventory数等于他本身,则输出该行;
例如: 21221314 -> 31321314 -> (31321314),输出: 21221314 is self-inventorying after 2 steps 
3) n enters an inventory loop of length k  
仍然用n的序列说明: n[0]->n[1]->n[2]…n[j]…n[i]…. (0<=j<i<=15),当n[i]的Inventory数(记作n[k]) 等于n[0]…n[i-1]的中n[j]时,那么很显然,再求下会形成一个循环;因此我们要找出是否存在最小(k>=1)使得n序列够成循环,输出这个k; 
例如: 314213241519 --> 412223241519 -->314213241519,对应上述的n[j] --> n[i] -> (n[k])  
4) n can not be classified after 15 iterations 
如果在找出15个数后,没有满足上述的任何一条,那么就输出该行;
*/
#include <stdio.h>
#include <string.h>
char s[16][85];
int turn,k;
void compress(int n,int t)
{   
	int times[10]={0};  //记录数字出现次数   
	int i,dec,sin;   
	if(t<=15)//15 iterative   
	{        
		for(i=0; i<strlen(s[n]); i++)        
		{          
			times[s[n][i]-'0']++;        
		}        
		k=0;        
		for(i=0; i<=9 ;i++)//重写字符串     
		{           
			if(times[i]>9)//如果该数字的个数大于9           
			{            
				dec=times[i]/10; //十位            
				sin=times[i]%10; //个位             
				s[t][k++]=dec+'0';             
				s[t][k++]=sin+'0';              
				s[t][k++]=i+'0';           
			}
			else if(times[i]>0)//如果该数字的个数为1~8 
			{
				s[t][k++]=times[i]+'0';
				s[t][k++]=i+'0';
			}       
		}      
		s[t][k]='\0';//字符串末尾添加结束符 
		compress(t,t+1);//继续找重写的字符串 
	}    
}
int main()
{   
	int flag1,flag2,flag3,i,j;
	while( scanf("%s",s[0])!=EOF && s[0][0]!='-')//如果是负数就退出循环 
	{       
		flag1=0;
		flag2=0;
		flag3=0;
		i=0,j=0;
		turn=1;
		compress(0,turn);//寻找 
		if(strcmp(s[0],s[1])==0)//如果第一次就相等 
		{        
			printf("%s is self-inventorying\n",s[0]);
			flag1=1;//说明已找到       
		}    
		if(!flag1)    
		{         
			for(i=1; i<15 ; i++)         
			{           
				if(strcmp(s[i],s[i+1])==0)           
				{               
					printf("%s is self-inventorying after %d steps\n",s[0],i);              
					flag2=1;              
					break;           
				}         
			}                  
			if(!flag2)         
			{                
				for(j=1; j<16; j++)           
				{             
					for(i=0; i<=j-2; i++)             
					{               
						if(strcmp(s[j],s[i])==0)
						{                 
							printf("%s enters an inventory loop of length %d\n",s[0],j-i);                 
							flag3=1;                 
							break;               
						}             
					}              
					if(flag3)               
					break;           
				}           
			}    
		}    
		if(!flag3 && !flag2 && !flag1)//如果都没有找到    
		{          
			printf("%s can not be classified after 15 iterations\n",s[0]);     
		}       
		getchar();//读取'\n' 
	}  
	return 0;   
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值