大致题意:给你连个长度分别为n1,n2且每列高度只为1或2的长条,然后将他们拼在一起,高度不能超过3,问他们拼在一起的最短长度。
Sample Input
2112112112
2212112
12121212
21212121
2211221122
21212
Sample Output
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,最好不要用。以后设置标识符时要见名知其意!