UVA-1588 紫書習題3-11換抵擋裝置
阿新 • • 發佈:2018-12-20
大致題意:給你連個長度分別為n1,n2且每列高度只為1或2的長條,然後將他們拼在一起,高度不能超過3,問他們拼在一起的最短長度。
Sample Input
2112112112
2212112
12121212
21212121
2211221122
21212
Sample Output
10
8
15
本體思路:
剛開始我的思路是先讓短的在下面,讓上面的不動,通過移動下面的長條來逐一比較,當長條從左到右移動完了之後,就能找到最短。但是程式碼交上去之後 樣例能通過但是一直WA,可能較複雜的資料過不了。(錯誤的思路)
後來看了一下網上的題解,也是通過移動下面的來進行比較,不同的是,它是讓兩個長條都從第一個元素開始比較,從左到右移動下面的長條。比較完之後,再將上下長條顛倒位置,再比較一遍,這樣就將全部的情況都比較完了。他的這種程式碼書寫很簡單,很值得我借鑑。(正確的思路)
我的程式碼:(錯誤的)
#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; }
借鑑的程式碼:
#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; }
知識點:
1、將字串轉化為數字時,我開的陣列太小了 導致一開始一直WA不知道為什麼。下次要注意陣列是否夠大。將數字在字元轉化為數字時,用a[i]-'0';
2、用flag,win做標記時,注意放在的位置,為了更新資料。本題應注意是將flag=1放在for的裡面還是要放在外面。一開始我的程式碼就因為放錯位置了導致找了半天錯誤才找到。很重要的一個知識點,要記得長記性。
3、可以通過輸出中間資料來檢查程式碼出現的問題。
4、不要用長得很像的識別符號!例如,a,a1,最好不要用。以後設定識別符號時要見名知其意!