1. %.3f保留3位小數並四舍五入
2. &&的優先級要高與||和&&有點類似於*,||類似於+
3:
1 if(1) 2 if(b) 3 x++; 4 else //else默認和最近的一個if配對 5 y++;
4. if(fabs(m*my-n*ny)<0.000001)
//浮點數判斷相等,要近似判斷,如果用==得不到結果。
//fabs(float x)浮點數x的絕對值 來源 藍橋杯 雞蛋的數目
5. 質數:又稱素數:在大於1的自然數中,除了1和它本身以外不再有其他因數。
6. 互質數:公因數只有1的兩個非零自然數
7. 同余定理: 例如:1234%10
1234%10=(((1%10*10+2)%10*10+3)%10*10+4)%10
8. 高次方數的尾數:
規律:1-100中 凡是有因子5,尾數就增加一個零;有因子25,尾數就增加兩個零。
100!有24個零,1000!有249個零。
9. 大衍數列 0、2、4、8、12、18、24、32、40、50、60、72、84...
1 int main() 2 { 3 int i; 4 for(i=1; i<100; i++) 5 { 6 if(i%2==0) //填空 7 printf("%d \n", i*i/2); 8 else 9 printf("%d \n", (i*i-1)/2); 10 } 11 printf("\n"); 12 }
10: 數字規律:1,3,6,10,,,,
公式:i*(i+1)/2
11:唯一分解定理:
1 ll getfac(ll x)//唯一分解定理 2 { 3 ll ans=1; 4 for(int i=1;i<=cnt&&primel[i]*primel[i]<=x;i++) 5 { 6 ll sum=0; 7 while(x%primel[i]==0) 8 { 9 sum++; 10 x/=primel[i]; 11 } 12 ans*=(sum+1); 13 } 14 if(x>1) 15 ans*=2; 16 return ans; 17 }
12: 一年的12個月:1-12月
31、28/29、31、30、31、30、31、31、30、31、30、31
閏年: (year%4==0&&year%100!=0)||(year%400==0)
13: 輾轉相除法求最大公約數
1 int gcd(int a, int b) 2 { 3 if (b == 0) return a; 4 else return gcd(b, a % b); 5 }
14:埃氏篩法(搜索n以內的所有素數)
1 int prime[MAX_N];//第i個素數 2 bool is_prime[MAX_N + 1]; 3 4 //返回n以內素數的個數 5 int sieve(int n) { 6 int p = 0; 7 for (int i = 0; i <= n; i++) 8 is_prime[i] = true; 9 is_prime[0] = is_prime[1] = false; 10 for (int i = 2; i <= n; i++) { 11 if (is_prime[i]){ 12 prime[p++] = i; 13 for (int j = 2*i; j <= n; j += i) 14 is_prime[j] = false; 15 } 16 } 17 return p; 18 }
15:篩選法求素數
1 memset(vis,0,sizeof(vis)); 2 for (int i=2;i<=n;i++) 3 { 4 for (int j=i*2;j<=n;j+=i) vis[j]=1; 5 }
升級版 素數定理 不超過x的素數個數近似(略超過) x/lnx;
1 int m=sqrt(n+0.5); 2 memset(vis,0,sizeof(vis)); 3 for (int i=2;i<=m;i++) 4 if (!vis[i]) 5 for (int j=i*i;j<=n;j+=i) vis[j]=1;
16:.快速冪取模
1 long long quick_mod(long long a,long long b){ 2 long long res=1; 3 while(b!=0){ 4 if (b%2==1) res*=(a%n); 5 a=a*(a%n); 6 b/=2; 7 } 8 return res; 9 }
但是當數據量大於10^19時,longlong會爆,所以利用快速乘法,原理類似,a*b就是b個a相加,將b表示為二進制:
1 int n; 2 long long mul(long long a,long long b){ 3 long long res=0; 4 while(b!=0){ 5 if(b%2==1) res=(res+a%n)%n; 6 a=(a%n+a%n)%n; 7 b/=2; 8 } 9 return res; 10 } 11 12 long long quick_mod(long long a,long long b){ 13 long long res=1; 14 while(b!=0){ 15 if (b%2==1) res=mul(res,a)%n; 16 a=mul(a,a); 17 b/=2; 18 } 19 return res; 20 }
17:二分排序
1 /* nums[]指的是有序數組;low指的是數組下標0;high指的是數組下標n-1(n指的是數組長度);target指的是要插入的目標元素 */ 2 void sort(int nums[],int low,int high,int target) { 3 int n=high+1; 4 // 當low<=high一直循環折半查找,當low>high時結束循環 5 while(low<=high) { 6 int mid=(low+high)/2;// 計算中間下標 7 if(nums[mid]>=target) { // 如果大於等於要插入的元素,則high=mid-1 8 high=mid-1; 9 } else if(nums[mid]<target) { // 如果小於要插入的元素,在low=mid+1 10 low=mid+1; 11 } 12 } 13 // 然后將nums[high+1]之后的所有元素(包括nums[high+1])向后移動一個位置 14 for(int i=n; i>high+1; i--) { 15 nums[i]=nums[i-1]; 16 } 17 // 然后將空出來的nums[high+1]賦為target值 18 nums[high+1]=target; 19 }
18:錯排 An=n-1(An-1+An-2)
19:進制轉換
1 #include "stdio.h" 2 int a[10000]; 3 int main() 4 { 5 int r,n; 6 char d; 7 while(~scanf("%d%d",&n,&r)) 8 { 9 int e=n; 10 if(n<0) 11 n=-n; 12 int i=0,j; 13 while(n!=0) 14 { 15 a[i]=n%r; 16 n=n/r; 17 i++; 18 } 19 for(j=i-1; j>=0; j--) 20 { 21 if(e<0) 22 { 23 if(j==i-1) 24 printf("-"); 25 if(a[j]>9) 26 { 27 d=a[j]-10+'A'; 28 printf("%c",d); 29 } 30 else 31 printf("%d",a[j]); 32 } 33 else 34 { 35 if(a[j]>9) 36 { 37 d=a[j]-10+'A'; 38 printf("%c",d); 39 } 40 else 41 printf("%d",a[j]); 42 } 43 } 44 printf("\n"); 45 } 46 return 0; 47 }
20: 01背包
解決辦法:聲明一個 大小為 m[n][c] 的二維數組,m[ i ][ j ] 表示 在面對第 i 件物品,且背包容量為 j 時所能獲得的最大價值 ,那么我們可以很容易分析得出 m[i][j] 的計算方法,
(1). j < w[i] 的情況,這時候背包容量不足以放下第 i 件物品,只能選擇不拿
m[ i ][ j ] = m[ i-1 ][ j ]
(2). j>=w[i] 的情況,這時背包容量可以放下第 i 件物品,我們就要考慮拿這件物品是否能獲取更大的價值。
如果拿取,m[ i ][ j ]=m[ i-1 ][ j-w[ i ] ] + v[ i ]。 這里的m[ i-1 ][ j-w[ i ] ]指的就是考慮了i-1件物品,背包容量為j-w[i]時的最大價值,也是相當於為第i件物品騰出了w[i]的空間。
如果不拿,m[ i ][ j ] = m[ i-1 ][ j ] , 同(1)
究竟是拿還是不拿,自然是比較這兩種情況那種價值最大。
1 if(j>=w[i]) 2 m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]); 3 else 4 m[i][j]=m[i-1][j];
21:完全背包問題
完全背包表示每個物品可以取無限次,只要加起來總容量不超過V就可以。
同樣可以用f[i][j]表示前i間物品恰放入一個容器為j的背包可以獲得的最大價值。則其狀態轉移方程為:
f[i][j] = max{f[i-1][j-k*weight[i]] + k*value[i]} ,其中(0 <= k <= j/weight[i])
22:多重背包問題
多重背包是每個物品有不同的個數限制,如第i個物品個數為num[i]。
同樣可以用f[i][j]表示前i間物品恰放入一個容器為j的背包可以獲得的最大價值,且每個物品數量不超多num[i]。則其狀態轉移方程為:
f[i][j] = max{f[i-1][j-k*weight[i]] + k*value[i]} ,其中(0 <= k <= min{j/weight[i], num[i]})