1. N 階乘末尾0的個數。
輸入描述:
輸入爲一行,n(1 ≤ n ≤ 1000)
輸出描述:
輸出一個整數,即題目所求
解法:要判斷末尾有幾個0就是判斷可以整除幾次10。10的因子有5和2,而在0~9之間5的倍數只有一個,2的倍數相對較多,所以本題也就轉換成了求N階乘中有幾個5的倍數。
也就是每多出來一個5,階乘末尾就會多出來一個0,這樣n / 5就能統計完第一層5的個數,依次處理,就能統計出來所有5的個數。同一個思想兩種寫法。
題解:
要判斷末尾有幾個0就是判斷可以整除幾次10。10的因子有5和2,而在0~9之間5的倍數只有一個,2的倍數相對較多,所以本題也就轉換成了求N階乘中有幾個5的倍數。
也就是每多出來一個5,階乘末尾就會多出來一個0,這樣n / 5就能統計完第一層5的個數,依次處理,就能統計出來所有5的個數。同一個思想兩種寫法。
參考代碼:
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int n; 6 cin>>n; 7 int count = 0; 8 while(n) 9 { 10 n /= 5; //算出當前數字中可以匹配5(5和5的倍數)的個數 11 count += n; //累加之 12 } 13 cout<<count; 14 return 0; 15 }
public class Main { public int calcuZero(int n) { int count = 0; for (int i = 1; i <= n; i++) { int cur = i; //如果因數中有一個5那麼乘積中就會有一個0,所以計算每一個i中因數5的個數 while (cur % 5 == 0) { count++; cur /= 5; } } return count; } public static void main(String[] args) { System.out.println(new Main().calcuZero(30)); } }
2.對稱二叉樹
題解:
判斷一個數是否爲鏡像對稱:先判斷根,在判斷左右子樹。如果左右子樹都爲空那就是,如果左右子樹不是同時爲空那就不是
當左右子樹都存在的時候,判斷他們的值是否相等,如果相等那麼久遞歸的對他們的字節點判斷(左邊的左=右邊的右;左邊的右==右邊的左)
參考代碼:
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isSymmetric(TreeNode *root) { if (!root) return true; return Symmetric(root->left, root->right); } bool Symmetric(TreeNode *left, TreeNode *right){ if (!left && !right) return true; if (!left || !right) return false; if (left->val == right->val){ return (Symmetric(left->left, right->right) && Symmetric(right->left, left->right)); } return false; } };
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean isSymmetric(TreeNode root) { if(root==null) return true; return work(root.left,root.right); } public boolean work(TreeNode l,TreeNode r) { if(l==null && r==null) return true; if(l==null || r==null) return false; if(l.val==r.val) { return work(l.left,r.right) && work(l.right,r.left); } else return false; } }
3.給定數組,從數組中取出n個不復用的數的和爲sum
題解;
一. DFS
參考代碼:
void findd(vector<int>&vr,int pos,int sum,int m,int& res){ if(sum==m){ res++; return; } else if(sum>m){ return; }else{ if(pos<vr.size()){ sum+=vr[pos]; findd(vr,pos+1,sum,m,res); sum-=vr[pos]; findd(vr,pos+1,sum,m,res); } } }
二. DP
dp[i][j]:表示前i個數,和爲j時有多少種情況。
轉移方程: dp[i][j]=dp[i-1][j]+dp[i-1][j-v[i]](j>=v[i]);
dp[i][j]=dp[i-1][j];(j<v[i])
參考代碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n=0; 6 int m=0; 7 while(cin>>n>>m){ 8 vector<int> vr(n); 9 for(int i=0;i<n;++i){ 10 cin>>vr[i]; 11 } 12 sort(vr.begin(),vr.end(),greater<int>()); 13 vector<vector<long long int>>dp(n,vector<long long int>(m+1,0)); 14 for(int i=0;i<n;++i){ 15 dp[i][0]=1; 16 } 17 for(int i=1;i<=m;i++){ 18 if(vr[0]>m)//過濾 19 break; 20 if(vr[0]==i) 21 dp[0][i]=1; 22 else 23 dp[0][i]=0; 24 } 25 for(int i=1;i<n;++i){ 26 if(vr[i]>m) //過濾 27 continue; 28 for(int j=1;j<=m;++j){ 29 if(j-vr[i]>=0) 30 dp[i][j]=dp[i-1][j]+dp[i-1][j-vr[i]]; 31 else 32 dp[i][j]=dp[i-1][j]; 33 } 34 } 35 cout<<dp[n-1][m]<<endl; 36 } 37 return 0; 38 } 39
未完待續~