A題:空間
根據:
1MB = 1024KB
1KB = 1024B
1B = 8bit
由題可知
32bit = 4B
直接模擬即可
#include <iostream> using namespace std; int main () { cout << 256 * 1024 * 1024 / 4 <<endl; return 0; }
答案:67108864
B題:卡片
定義十個下標0-9的數組,每個數組包含數字2021,可表示為每個0-9的數字有2021個。
定義i=1表示為從1開始排數,取 i mod 10 的余數,對於每個余數a[i % 10] -- 即可,直到把某個數字減完。
1 #include <iostream> 2 using namespace std; 3 4 int main () 5 { 6 int a[10] = {2021,2021,2021,2021,2021,2021,2021,2021,2021,2021}; 7 8 int res = 0; 9 int i = 1; 10 while (i) 11 { 12 int k = i; 13 while (k) 14 { 15 if (a[k%10] == 0) 16 { 17 cout << res <<endl; 18 return 0; 19 } 20 a[k % 10] -- ; 21 k /= 10; 22 23 } 24 res++; 25 i ++; 26 } 27 28 return 0; 29 }
答案:3181
C題:直線
設直線方程y = kx + m;
根據直線性質:
斜率k = (y1 - y2) / (x1 - x2)
截距b = m
枚舉每個點,這里需要注意的是,由於垂直線不存在斜率,所以當x1 = x2的時候不枚舉。
定義Line結構體儲存k,b。
在誤差1e-8之內可算作同一條直線。
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 6 using namespace std; 7 8 const int N = 200000; 9 10 int n; 11 struct Line 12 { 13 double k, b; 14 bool operator< (const Line& t) const 15 { 16 if (k != t.k) return k < t.k; 17 return b < t.b; 18 } 19 }l[N]; 20 21 int main() 22 { 23 for (int x1 = 0; x1 < 20; x1 ++ ) 24 for (int y1 = 0; y1 < 21; y1 ++ ) 25 for (int x2 = 0; x2 < 20; x2 ++ ) 26 for (int y2 = 0; y2 < 21; y2 ++ ) 27 if (x1 != x2) 28 { 29 double k = (double)(y2 - y1) / (x2 - x1); 30 double b = y1 - k * x1; 31 l[n ++ ] = {k, b}; 32 } 33 34 sort(l, l + n); 35 int res = 1; 36 for (int i = 1; i < n; i ++ ) 37 if (fabs(l[i].k - l[i - 1].k) > 1e-8 || fabs(l[i].b - l[i - 1].b) > 1e-8) 38 res ++ ; 39 cout << res + 20 << endl; 40 41 return 0; 42 }
答案:40257
D題:貨物擺放
用試除法枚舉2021041820210418的每一個約數
直接遍歷即可。
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 const int N = 1000010; 5 vector<long long> q; 6 7 int main () 8 { 9 int res = 0; 10 long long n = 2021041820210418; 11 12 for (long long i = 1 ; i * i <= n ; i ++ ) 13 { 14 if (n % i == 0) 15 { 16 q.push_back(i); 17 if (n / i != i ) q.push_back(n / i); 18 } 19 } 20 21 for (int a = 0 ; a < q.size() ; a++ ) 22 for (int b = 0 ; b < q.size() ; b ++ ) 23 for (int c = 0 ; c < q.size() ; c ++) 24 { 25 if (q[a] * q[b] * q[c] == n) 26 res++; 27 } 28 29 cout << res <<endl; 30 return 0; 31 }
答案:2430
F題:時間顯示
題目只要求輸出時分秒,所以可以先把N =/ 1000。
然后用N對一天之內的秒數取模,即 N %= 86400。
直接模擬即可。
#include <iostream> using namespace std; typedef long long LL; int main() { LL n; cin >> n; n /= 1000; n %= 86400; int h = n / 3600; n %= 3600; int m = n / 60; int s = n % 60; printf("%02d:%02d:%02d\n", h, m, s); return 0; }
H題:楊輝三角形
由於求的是數字第一次出現的位置,所以可以對楊輝三角軸對稱切半,觀察斜行。
不難發現除了第一斜行,每一斜行都是遞增,因為C(n,m)n越大值越大,同理每一行也是遞增。
根據楊輝三角性質可知:
1.每個數都會在楊輝三角的左半邊出現
2.對於第n行第m個數字,其值為C(n-1,m-1)
3.在第35行18個時,C(34,17)> 109
上述可知,用二分可快速求出當前數第一次出現的次數。
1 #include <iostream> 2 using namespace std; 3 typedef long long ll; 4 5 int n; 6 7 ll bsearch(int a, int b) 8 { 9 ll res = 1; 10 for(int i = a, j = 1; j <= b; i--, j++) 11 { 12 res = res * i / j; 13 if(res > n) return res; 14 } 15 return res; 16 } 17 18 int check(int k) 19 { 20 ll l = 2 * k, r = n; 21 while(l < r) // 二分查找 22 { 23 int mid = l + r >> 1; 24 if(bsearch(mid, k) >= n) r = mid; 25 else l = mid + 1; 26 } 27 if(bsearch(r, k) != n) return 0; 28 cout << r * (r + 1) / 2 + k + 1 << endl; 29 return 1; 30 } 31 32 int main() 33 { 34 cin >> n; 35 36 for(int k = 16; ; k--) 37 if(check(k)) break; 38 return 0; 39 }