UVA-1588 紫书习题3-11换抵挡装置

大致题意:给你连个长度分别为n1,n2且每列高度只为1或2的长条,然后将他们拼在一起,高度不能超过3,问他们拼在一起的最短长度。

 Sample Input

2112112112

2212112

12121212

21212121

2211221122

21212

Sample Output

扫描二维码关注公众号,回复: 4097081 查看本文章

10

8

15

本体思路: 

刚开始我的思路是先让短的在下面,让上面的不动,通过移动下面的长条来逐一比较,当长条从左到右移动完了之后,就能找到最短。但是代码交上去之后 样例能通过但是一直WA,可能较复杂的数据过不了。(错误的思路)

后来看了一下网上的题解,也是通过移动下面的来进行比较,不同的是,它是让两个长条都从第一个元素开始比较,从左到右移动下面的长条。比较完之后,再将上下长条颠倒位置,再比较一遍,这样就将全部的情况都比较完了。他的这种代码书写很简单,很值得我借鉴。(正确的思路) 

借鉴的代码:(AC)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
    char a[105],b[105];
    int aa[205],bb[205];///数组要开足够大  数组空间不够时也会WA
    while(~scanf("%s%s",a,b))
    {
        int lena=strlen(a);
        int lenb=strlen(b);
        memset(aa,0,sizeof(aa));
        memset(bb,0,sizeof(bb));
        int ans1,ans2,ans;
        int i,j;
        for(i=0;i<lena;i++)///将字符转化为对应的数字
            aa[i]=a[i]-'0';
        for(i=0;i<lenb;i++)
            bb[i]=b[i]-'0';
        for(i=0;i<lena;i++)///先让a串在上面b串在下面,通过移动b串来比较
        {
            for(j=0;j<lenb;j++)
            {
                if(aa[i+j]+bb[j]>3)
                    break;
            }
            if(j==lenb)////说明都比较一遍之后串a和串b都相等 比较完了之后j==lenb
                break;
        }
        if(i+lenb>lena) ans1=i+lenb;
        else  ans1=lena;
        ///代码和上面的相似
        for(i=0;i<lenb;i++)///然后颠倒位置,让b串在上面a串在下面,通过移动a串来比较
        {
            for(j=0;j<lena;j++)
            {
                if(bb[i+j]+aa[j]>3)
                    break;
            }
            if(j==lena)  break;
        }
        if(i+lena>lenb)  ans2=i+lena;
        else   ans2=lenb;
        ans=min(ans1,ans2);
        printf("%d\n",ans);///最终选取两种方式中较小的;
    }
    return 0;
}

我的代码:(错误的) 

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
    char a[105],b[105];
    int a1[205],b1[205];
    while(~scanf("%s%s",a,b))
    {
        int len1=strlen(a);
        int len2=strlen(b);
        if(len1<len2)
        {
            for(int i=0;i<len2;i++)
                a1[i]=b[i]-'0';
            for(int i=0;i<len2;i++)
                b1[i]=a[i]-'0';
            swap(len1,len2);
        }
        else
        {
            for(int i=0;i<len1;i++)
                a1[i]=a[i]-'0';
            for(int i=0;i<len2;i++)
                b1[i]=b[i]-'0';
        }
        int flag;
        int sum,ans=len1+len2;
        for(int j=len2-1;j>=0;j--)
        {
            flag=1;///更新数据
            for(int k=0;k<len2-j&&j+k<len2;k++)
            {
                if(a1[k]==2&&b1[j+k]==2)
				{flag=0;break;}
            }
            if(flag==0) continue;
            else {/*cout<<"flag="<<flag<<"  "<<j<<endl;*/sum=len1+j;}
            if(sum<ans)
                ans=sum;
        }
		int win;int i,j;
		for(i=0;i<len1;i++)
		{
			win=1;///更新数据
			for(j=0;j<len2&&i+j<len1;j++)
			{
				if(a1[i+j]==2&&b1[j]==2)
				{win=0;break;}
			}
			if(win==0) continue;
			else {/*cout<<"win="<<win<<endl;*/sum=len1;}
			if(sum<ans)
				ans=sum;
		}
		cout<<ans<<endl;
		//cout<<i<<"  "<<j<<endl;

    }
    return 0;
}

知识点:

1、将字符串转化为数字时,我开的数组太小了  导致一开始一直WA不知道为什么。下次要注意数组是否够大。将数字在字符转化为数字时,用a[i]-'0';

2、用flag,win做标记时,注意放在的位置,为了更新数据。本题应注意是将flag=1放在for的里面还是要放在外面。一开始我的代码就因为放错位置了导致找了半天错误才找到。很重要的一个知识点,要记得长记性。

3、可以通过输出中间数据来检查代码出现的问题。

4、不要用长得很像的标识符!例如,a,a1,最好不要用。以后设置标识符时要见名知其意!

猜你喜欢

转载自blog.csdn.net/an94460061/article/details/83961467
今日推荐