問題 B: 弟弟的做業 時間限制: 1 Sec 內存限制: 128 MB 提交: 80 解決: 41 外部導入 提交狀態討論版 題目描述 你的弟弟剛作完了「100之內數的加減法」這部分的做業,請你幫他檢查一下。每道題目(包括弟弟的答案)的格式爲a+b=c或者a-b=c,其中a和b是做業中給出的,均爲不超過100的非負整數;c是弟弟算出的答案,多是不超過200的非負整數,也多是單個字符"?",表示他不會算。 輸入 輸入文件包含不超過100行,以文件結束符結尾。每行包含一道題目,格式保證符合上述規定,且不包含任何空白字符。輸入的全部整數均不含前導0。 輸出 輸出僅一行,包含一個非負整數,即弟弟答對的題目數量。 樣例輸入 Copy 1+2=3 3-1=5 6+7=? 99-0=99 樣例輸出 Copy 2
int main() { char s[30]; int a,b,c; int sum=0; while(scanf("%s",&s)!=EOF) { if(sscanf(s,"%d+%d=%d",&a,&b,&c)==3&&(a+b==c)) sum++; if(sscanf(s,"%d-%d=%d",&a,&b,&c)==3&&(a-b==c)) sum++; } cout<<sum<<endl; return 0; }
其實這個題目就只要判斷「=」後面的數整部正確而且是否是「?」;若是是「?」的話就無論,不是的話再判斷是否是正確的數,若是是正確的是,那麼sum++;算法
另外一種思路就是用atof()函數,在逆波蘭表達式中提到過這個函數的一丟丟用法;數組
以文件結尾結束就是 crl+z會輸出sum的答案函數
問題 C: 求解n階螺旋矩陣問題 時間限制: 1 Sec 內存限制: 128 MB 提交: 0 解決: 0 201501010119 提交狀態討論版 題目描述 建立n階螺旋矩陣並輸出。 輸入 輸入包含多個測試用例,每一個測試用例爲一行,包含一個正整數n(1<=n<=50),以輸入0表示結束。 輸出 每一個測試用例輸出n行,每行包括n個整數,整數之間用一個空格分割。 樣例輸入 Copy 4 0 樣例輸出 Copy 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7
int a[55][55]; int main() { int n,i,j,b; while(scanf("%d",&n)&&n) { int flag=1; for(b=0;b<=(n+1)/2;b++) { for(j=b;j<=n-b-1;j++) a[b][j]=flag++; for(i=b+1;i<n-b-1;i++) a[i][n-b-1]=flag++; for(j=n-b-1;j>b;j--) a[n-b-1][j]=flag++; for(i=n-b-1;i>b;i--) a[i][b]=flag++; } for(i=0;i<n;i++) { for(j=0;j<n;j++) if(j==0) cout<<a[i][j]; else cout<<" "<<a[i][j]; cout<<endl; } } return 0; }
問題 D: 最大子段和 時間限制: 1 Sec 內存限制: 128 MB 提交: 1 解決: 1 201501010119 提交狀態討論版 題目描述 給定n個整數(多是負數)組成的序列a[1], a[2], a[3], …, a[n],求該序列的子段和如a[i]+a[i+1]+…+a[j]的最大值。 輸入 每組輸入包括兩行,第一行爲序列長度n,第二行爲序列。 輸出 輸出字段和的最大值。 樣例輸入 Copy 5 -1 0 1 2 3 樣例輸出 Copy 6
int a[1000]; int n; int maxx(int a[],int n) { int b,sum; if(a[0]>0) b=a[0]; //判斷第一個數是否爲正,爲正直接加,爲負將b賦值爲0; else b=0; sum=b; //sum用來找b中的最大值(也就是找子段和中最大的子段和) for(int i=1;i<n;i++) { if(b>0) //若是b爲正,就一直加(無論a[i]是否爲負,只要b爲正,都要一直加a[i]) b=b+a[i]; else //直到b爲負,那麼就無論這個子段了,從新從a[i]開始算另外一個子段和 b=a[i]; if(b>sum) //取衆多子段的最大的那個子段 sum=b; } return sum; } int main() { while(cin>>n) { int i; for(i=0;i<n;i++) cin>>a[i]; cout<<maxx(a,n)<<endl; } return 0; }
動態規劃法;測試
b[i]表示以a[i]結尾的子段和;spa
判斷b[i-1]是否爲正,爲正的話:b[i-1]+a[i]放在b[i]裏;不然,就從下一個子段開始,而且判斷每次加的子段的最大值,輸出的是最大值sum。code
![](http://static.javashuo.com/static/loading.gif)
問題 F: 牛牛的字符串 時間限制: 1 Sec 內存限制: 128 MB 提交: 1 解決: 1 201501010119 提交狀態討論版 題目描述 牛牛有兩個字符串(可能包含空格),他想找出其中最長的公共連續子串的長度,但願你能幫助他。例如:兩個字符串分別爲"abede"和"abgde",結果爲2。 輸入 每組數據包括兩行,每行爲一個字符串。 輸出 輸出最長的公共連續子串的長度。 樣例輸入 Copy abede abgde 樣例輸出 Copy 2
int dp[1000][1000]; char a[1000],b[1000]; int maxx=0; int lsc(int x,int y) { int i,j; for(i=0;i<x;i++) { if(a[i]==b[0]) dp[i][0]=1; } for(j=0;j<y;j++) { if(b[j]==a[0]) dp[0][j]=1; } for(i=1;i<x;i++) for(j=1;j<y;j++) { if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; if(dp[i][j]>=maxx) maxx=dp[i][j]; } return maxx; } int main() { while(cin>>a) { cin>>b; int x=strlen(a); int y=strlen(b); cout<<lsc(x,y)<<endl;; } return 0; }
這個代碼仍是有點問題的,由於當輸入的兩個字符串某個長度爲1的時候會輸出0,因此咱們在主函數中判斷一下字符串長度是否爲1,爲1的話就直接線性查找;blog
最長公共子序列:要求相對位置一致就行;遞歸
dp[i][j]表示x從第一個到第i個,y從第一個到第j個;內存
填表法:長的爲行,短的爲列,第一行第二行全0,若行列的兩個字母相同,dp數組=左上角的dp數組+1,不相等的話取上面和前面的最大值;ci
最後取右下角
問題 G: 最長公共子序列問題(LCS)-構造LCS 時間限制: 1 Sec 內存限制: 128 MB 提交: 2 解決: 1 201501010119 提交狀態討論版 題目描述 使用動態規劃算法求兩個序列的最長公共子序列,需構造一條最長公共子序列。 輸入 每組輸入包括兩行,每行包括一個字符串。 輸出 兩個字符序列的一條最長公共子序列。(輸入已確保最長公共子序列的惟一性) 樣例輸入 Copy acdbxx ccdxx 樣例輸出 Copy cdxx
char a[1000],b[1000]; int aa[100][100]; int dp[100][100]; void lcs(int i,int j) { if(i==0||j==0) //找完了,結束遞歸 return ; if(dp[i][j]==1) //先回溯,再輸出 { lcs(i-1,j-1); cout<<a[i-1]; } else if(dp[i][j]==2) lcs(i-1,j); else lcs(i,j-1); } int main() { memset(aa,0,sizeof(aa)); while(cin>>a) { cin>>b; int m=strlen(a); int n=strlen(b); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) { if(a[i-1]==b[j-1]) { aa[i][j]=aa[i-1][j-1]+1; dp[i][j]=1; } else { if(aa[i-1][j]>aa[i][j-1]) { aa[i][j]=aa[i-1][j]; dp[i][j]=2; } else { aa[i][j]=aa[i][j-1]; dp[i][j]=3; } } } lcs(m,n); } return 0; }
這是最簡單的狀況,只要求構造一條最長子序列;
dp數組用來記錄存進aa的值是來自上面仍是前面仍是左對角;
最後遞歸輸出;
問題 H: Max Sum 時間限制: 1 Sec 內存限制: 33 MB 提交: 0 解決: 0 201501010119 提交狀態討論版 題目描述 給你一個序列 a[1],a[2],a[3]......a[n], 你要作的是求出最大字段和. 好比, 輸入 6,-1,5,4,-7, 這個序列的最大字段和就是 6 + (-1) + 5 + 4 = 14. 輸入 The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000). 輸出 每組測試用例輸出兩行。 第一行是"Case #:" # 表示測試用例的序數。 第二行包括三個數字,最大子段和,以及子段的起始位置和結束位置 例如:輸入數組(6,-1,5,4,-7),輸出14, 1, 4,其中14表示最大子段和,1表示和最大的子段從第1個數字開始,4表示和最大的子段到第4個數字結束,即(6, -1 , 5, 4)。 樣例輸入 Copy 2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5 樣例輸出 Copy Case 1: 14 1 4 Case 2: 7 1 6
int a[1000]; int i,n; int be,ed,k,b,sum; int flag; void maxx(int a[],int n) { for(i=0;i<n;i++) { b=b+a[i]; if(b>sum) { sum=b; ed=i+1; be=k+1; } if(b<0) { b=0; k=i+1; } } return ; } int main() { int t; cin>>t; flag=0; while(t--) { cin>>n; for(i=0;i<n;i++) cin>>a[i]; be=0,ed=0,k=0,b=0,sum=-1; maxx(a,n); flag++; cout<<"Case "<<flag<<":"<<endl<<sum<<" "<<be<<" "<<ed<<endl; } return 0;