查看代码源文件 Visit Cai1Hsu/blog C/C++ 自动构建: 前往 GitHub
P8682 [蓝桥杯 2019 省 B] 等差数列 题目链接
题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中 N 个整数。
现在给出这N 个整数,小明想知道包含这N 个整数的最短的等差数列有几项?
输入输出样例 输入 #1 输出 #1 思路 要想找到有多少个数,先求出有公差。 要保证数最少,则公差必须大。 要构成等差数列,则公差 d 应满足 d <= min{d1, d2, d3, ..., dn} 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 int main (int argc, char * argv[]) { int n = cint (); vec<int > arr (n, 0 ) ; repeat (n, i) arr[i] = cint (); sort (all (arr)); int diff = 0x7fffffff ; range (1 , n, i) { diff = min (diff, arr[i] - arr[i - 1 ]); } int ans = arr.length; if (diff != 0 ) { ans = (arr.back () - arr.front () + (diff - 1 )) / diff + 1 ; } cout << ans; }
P1226 【模板】快速幂 题目链接
题目描述 给你三个整数 a, b, p,求 $a^b mod p。
输入格式 输入只有一行三个整数,分别代表 a, b, p。
输出格式 输出一行一个字符串 a^b mod p=s,其中 a, b, p 分别为题目给定的值, s 为运算结果。
样例 #1 样例输入 #1 样例输出 #1 提示 样例解释
2^10 = 10241024 mod 9 = 7
数据规模与约定
对于 100% 的数据,保证 0< a,b < 2^31,a + b > 0,2 <= p < 2^31。
思路 对于a, b,要求a ^ b,可以转化为( a ^ (b / 2) ) ^ 2。其中当b为奇数时,将结果再次乘以a即可。 为了保证结果始终在int范围内,同时保证结果已经取余,需要在每次做乘法运算后取模。 代码实现上,使用类似于CPU将乘法转化为加法的计算方法进行计算,我们将乘方的计算转化为乘法的计算,即: 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ll qpow (ll a, ll b) { ll ans = 1 ; ll p = a % mod; range (0 , 31 , i) { bool need_cur_p = (b >> i) & 1 ; if (need_cur_p) ans = ans * p % mod; p = p * p % mod; } return ans % mod; }
P2249 【深基13.例1】查找 题目链接
题目描述 输入 n 个不超过 10^9 的单调不减的(就是后面的数字不小于前面的数字)非负整数 a[1], a[2], ..., a[n],然后进行 m 次询问。对于每次询问,给出一个整数 q,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 -1 。
输入格式 第一行 2 个整数 n 和 m,表示数字个数和询问次数。
第二行 n 个整数,表示这些待查询的数字。
第三行 m 个整数,表示询问这些数字的编号,从 1 开始编号。
输出格式 输出一行,m 个整数,以空格隔开,表示答案。
思路1 由于 n <= 10 ^ 6,而10 ^ 6 * 4 * 2 = 7.7 MB,可以保证不会超出125 MB的限制,可以直接用散列表。 时间复杂度: O(m)(不考虑读入数据的时间) 空间复杂度 <= O(n) 代码1 本次提交使用了fastscan()代替cint()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int main () { int n = cint (), m = cint (); unordered_map<int , int > pos; crange (1 , n, i) { int x = cint (); if (!pos.count (x)) pos[x] = i; } while (m--) { int x = cint (); if (pos.count (x)) cout << pos[x] << " " ; else cout << "-1 " ; } }
思路2 二分查找 懒得写了
代码2 二分查找 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int binarysearch (const vector<int > &arr, int target) { int left = 0 , right = arr.size () - 1 ; while (left <= right) { int mid = left + (right - left) / 2 ; if (arr[mid] == target) { while (mid >= 0 && arr[mid] == target) mid--; return mid + 2 ; } if (arr[mid] < target) left = mid + 1 ; else right = mid - 1 ; } return -1 ; }
附:STL二分查找实现分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 Pointer lowerbound (Pointer first, Pointer last, int val) { int len = __distance(first, last) while (len > 0 ) { int half = len >> 1 ; Pointer middle = first; __advance(middle, half); if (__comp(middle, val)) { first = middle; ++first; len = len - half - 1 ; } else len = half; } return first; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Pointer upperbound (Pointer first, Pointer last, int val) { int len = __distance(first, last); while (len > 0 ) { int half = len >> 1 ; Pointer middle = first; std::advance (middle, half); if (comp (val, middle)) len = half; else { first = middle; ++first; len = len - half - 1 ; } } return first; }
P1824 进击的奶牛 题目描述 太长了自己去看: link
思路 二分查找,在范围内检测答案是否可行。 关键在于实现查找的函数和判断的函数
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 bool check (int gap) { int last = stalls[0 ]; int count = 1 ; range (1 , n, i) { if (stalls[i] - last >= gap) { count++; last = stalls[i]; } if (count >= c) return true ; } return false ; } int binarysearch () { int left = 0 , right = stalls.back () - stalls.front (); while (left < right) { int middle = (left + right + 1 ) >> 1 ; if (check (middle)) { left = middle; } else { right = middle - 1 ; } } return left; }
博客仓库 Cai1Hsu/blog
使用的宏 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <bits/stdc++.h> using namespace std;#define add append #define var auto #define in : #define all(a) begin(a), end(a) #define rall(a) rbegin(a), rend(a) #define pii pair<int, int> #define length size() #define mkpair make_pair #define pow2(x) (1 << (x)) #define each(a, b) for (auto a : b) #define foreach(a, b) for (auto a : b) #define rsort(a) sort(a.rbegin(), a.rend()) #define null NULL #define npr nullptr #define MOD (100000007) #define ll long long #define ld long double #define f32 float #define f64 double #define vi vector<int> #define vec vector #define range(begin,end, i) for(int i = begin; i < end; i++) #define crange(begin,end, i) range(begin, end + 1, i) #define repeat(times, i) range(0, times, i) #define endl '\n' void untie () { ios_base::sync_with_stdio (0 ); cin.tie (0 ); }int cint () { int i; cin >> i; return i;}