算法竞赛入门经典(第2版)习题3-11 换低挡装置 Kickdown UVa1588

逻辑如下

1.读入n1/n2,测量各自长度

2.设定容器的最小长度为minlen,minlen=max(n1,n2)

3.依次对比n1/n2,如果发现高度和为4则向右移动n2一格再次对比,最终得到容器长度l1,如果l1小于最小长度minlen,则l1=minlen

4.再次依次对比n1/n2,如果发现高度和为4则向右移动n1一格再次对比,最终得到容器长度l2,如果l2小于最小长度minlen,则l2=minlen

5.所求容器长度为min(l1,l2)

逻辑很简单,但是我最初没有考虑周全,实现上也出过数次错误

最后修正的一个错误是取n1/n2数据长度的时候没有考虑到n1长度等于1的情况,导致n1的长度取成了0.

第5次提交ac,耗时4小时。

1.scanf() 版输入

//#define LOCAL
//#define TESTING
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define MAXN 105

char n1[MAXN],n2[MAXN];

int main()
{
#ifdef LOCAL
	freopen("xt3-11.in","r",stdin);
#endif	
	memset(n1,0,sizeof(n1));		
	memset(n2,0,sizeof(n2));
	while(scanf("%s%s",n1,n2)==2)
	{
#ifdef TESTING
		int kase1 = 0,kase2 = 0;	
#endif		
		int len1 = 0,len2 = 0,n = 0, l1=0, l2=0,minlen=0;
		//读数据,取长度 
		len1 = strlen(n1);
		len2 = strlen(n2);
		for(int i = 0;i<len1; i++) n1[i]=n1[i]-'0';
		for(int i = 0;i<len2; i++) n2[i]=n2[i]-'0';
		//读数据,取长度结束
		
		if(len1<len2) minlen = len2;
		else minlen = len1;
		
		//计算n2右移情况下的容器最短长度l1 
			for(int i = 0; i <= len1; i++)
			{
				bool ok = false;
				if(i==len1)
				{
					l1 = len1+len2;
					#ifdef TESTING
					kase1 = 3;
					#endif
					break;
				}
				for(int j = 0; j < len2; j++)
				{
					if((i+j)<len1)
					{
						if((n1[i+j]+n2[j])==4) break;
						else if((j==len2-1)&&((n1[i+j]+n2[j])<4))
						{
							l1 = minlen;
							ok = true;
							#ifdef TESTING
							kase1 = 1;
							#endif
							break;
						}
					}
					else
					{
						l1 = len1+len2-j;
						#ifdef TESTING
						kase1 = 2;
						printf("l1=%d ",l1); 
						#endif
						ok = true;
					}
					if(ok) break;					
				} 
				if(ok) break;
			}
			if(l1<minlen) l1 = minlen;
		//计算n2右移情况下的容器最短长度l1 
		//计算n1右移情况下的容器最短长度l2
	
			for(int i = 0; i <= len2; i++)
			{
				bool ok = false;
				if(i==len2)
				{
					l2 = len1+len2;
					#ifdef TESTING
					kase2 = 3;
					#endif					
					break;
				}
				for(int j = 0; j < len1; j++)
				{
					if((i+j)<len2)
					{						
						if((n2[i+j]+n1[j])==4) break;
						else if((j==len1-1)&&((n2[i+j]+n1[j])<4))
						{
							l2 = minlen;
							#ifdef TESTING
							kase2 = 1;
							#endif							
							ok = true;
							break;
						}
					}
					else
					{
						l2 = len1+len2-j;
						#ifdef TESTING
						kase2 = 2;
						printf("l2=%d ",l2); 
						#endif						
						ok = true;
					}	
					if(ok) break;				
				} 
				if(ok) break;
			}
			if(l2<minlen) l2 = minlen;
		//计算n1右移情况下的容器最短长度l2结束 	
		//l1/l2取小	,
		if(l1<l2) n = l1;
		else 
		{
			n = l2;	
		}
		
		//l1/l2取小
		
#ifdef TESTING
	printf("case1=%d case2=%d l1=%d l2=%d\n",kase1,kase2, l1, l2);
	printf("n1 %d:",len1);
	for(int i = 0; i < len1; i++) printf("%d", n1[i]);
	printf("\n");
	printf("n2 %d:",len2);
	for(int i = 0; i < len2; i++) printf("%d", n2[i]);
	printf("\n\n");
#endif		
	printf("%d\n", n);	
	}
	return 0;
}


2.getchar() 版输入

//#define LOCAL
//#define TESTING
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define MAXN 105

int n1[MAXN],n2[MAXN];

int main()
{
#ifdef LOCAL
	freopen("xt3-11.in","r",stdin);
#endif
	int temp;		
	while((temp=getchar())!=EOF)
	{
#ifdef TESTING
		int kase1 = 0,kase2 = 0;
		printf("%d\n",temp);
#endif		
		int len1 = 0,len2 = 0,n = 0, l1=0, l2=0,minlen=0;
		//读数据,取长度 
		if(isdigit(temp)) n1[0] = temp - '0';		
		len1 = 1;
#ifdef TESTING		
		printf("%d\n",n1[0]);
#endif				
		for(int i = 1; i < MAXN; i++)
		{
			temp = getchar();
			if(isdigit(temp))
			{
				n1[i] = temp- '0';
				len1 = i+1;
			}
			else break;
		}		
		for(int i = 0; i < MAXN; i++)
		{
			temp = getchar();
			if(isdigit(temp))
			{
				n2[i] = temp- '0';
				len2 = i+1;
			}
			else break;
		}		
		//读数据,取长度结束
		
		if(len1<len2) minlen = len2;
		else minlen = len1;
		
		//计算n2右移情况下的容器最短长度l1 
			for(int i = 0; i <= len1; i++)
			{
				bool ok = false;
				if(i==len1)
				{
					l1 = len1+len2;
					#ifdef TESTING
					kase1 = 3;
					#endif
					break;
				}
				for(int j = 0; j < len2; j++)
				{
					if((i+j)<len1)
					{
						if((n1[i+j]+n2[j])==4) break;
						else if((j==len2-1)&&((n1[i+j]+n2[j])<4))
						{
							l1 = minlen;
							ok = true;
							#ifdef TESTING
							kase1 = 1;
							#endif
							break;
						}
					}
					else
					{
						l1 = len1+len2-j;
						#ifdef TESTING
						kase1 = 2;
						printf("l1=%d ",l1); 
						#endif
						ok = true;
					}
					if(ok) break;					
				} 
				if(ok) break;
			}
			if(l1<minlen) l1 = minlen;
		//计算n2右移情况下的容器最短长度l1 
		//计算n1右移情况下的容器最短长度l2
	
			for(int i = 0; i <= len2; i++)
			{
				bool ok = false;
				if(i==len2)
				{
					l2 = len1+len2;
					#ifdef TESTING
					kase2 = 3;
					#endif					
					break;
				}
				for(int j = 0; j < len1; j++)
				{
					if((i+j)<len2)
					{						
						if((n2[i+j]+n1[j])==4) break;
						else if((j==len1-1)&&((n2[i+j]+n1[j])<4))
						{
							l2 = minlen;
							#ifdef TESTING
							kase2 = 1;
							#endif							
							ok = true;
							break;
						}
					}
					else
					{
						l2 = len1+len2-j;
						#ifdef TESTING
						kase2 = 2;
						printf("l2=%d ",l2); 
						#endif						
						ok = true;
					}	
					if(ok) break;				
				} 
				if(ok) break;
			}
			if(l2<minlen) l2 = minlen;
		//计算n1右移情况下的容器最短长度l2结束 	
		//l1/l2取小
		if(l1<l2) n = l1;
		else 
		{
			n = l2;	
		}
		
		//l1/l2取小
		
#ifdef TESTING
	printf("case1=%d case2=%d l1=%d l2=%d\n",kase1,kase2, l1, l2);
	printf("n1 %d:",len1);
	for(int i = 0; i < len1; i++) printf("%d", n1[i]);
	printf("\n");
	printf("n2 %d:",len2);
	for(int i = 0; i < len2; i++) printf("%d", n2[i]);
	printf("\n\n");
#endif		
	printf("%d\n", n);	
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值