A
题意:判断一个字符串是否存在偶数长度回文子串。
思路:判断是否有两个字符相等即可。O(n)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 char s[105]; 45 int main() { 46 scanf("%s", s + 1); 47 int l = strlen(s + 1); 48 for (int i = 1; i < l; ++i) { 49 if (s[i] == s[i + 1]) { 50 puts("Or not."); 51 return 0; 52 } 53 } 54 puts("Odd."); 55 return 0; 56 }
B
题意:总共n种字符,判断一个n*n的方格
(1)是否每行都包含n种字符,每一列是否都包含n种字符;
(2)在满足性质(1)的情况下判断第一行和第一列元素是否严格上升
思路:按上述题意模拟即可。O(n*n)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n; 45 char s[41][41]; 46 set<char> ss; 47 int main() { 48 while (~scanf("%d", &n)) { 49 int flag = 0; 50 for (int i = 1; i <= n; ++i) { 51 scanf("%s", s[i] + 1); 52 } 53 for (int i = 1; i <= n; ++i) { 54 ss.clear(); 55 for (int j = 1; j <= n; ++j) { 56 ss.insert(s[i][j]); 57 } 58 if (n != ss.size()) { 59 puts("No"); 60 flag = 1; 61 break; 62 } 63 } 64 if (flag) continue; 65 for (int j = 1; j <= n; ++j) { 66 ss.clear(); 67 for (int i = 1; i <= n; ++i) { 68 ss.insert(s[i][j]); 69 } 70 if (n != ss.size()) { 71 puts("No"); 72 flag = 1; 73 break; 74 } 75 } 76 if (flag) continue; 77 for (int i = 2; i <= n; ++i) { 78 if (s[i][1] < s[i - 1][1]) { 79 puts("Not Reduced"); 80 flag = 1; 81 break; 82 } 83 } 84 if (flag) continue; 85 for (int j = 2; j <= n; ++j) { 86 if (s[1][j] < s[1][j - 1]) { 87 puts("Not Reduced"); 88 flag = 1; 89 break; 90 } 91 } 92 if (flag) continue; 93 puts("Reduced"); 94 } 95 return 0; 96 }
C
题意:定义f(x)为x的约数个数,求SUM(f(x)) (a <= x <= b)
思路:枚举小于等于1e6的因子,对于每一个因子y, a 到 b之间能整出y的个数为 b/y(向下取整) - a/y(向上取整)+ 1,a 到 b 之间能整除y之后剩的因子为 b/y(向下取整), ..., a/y(向上取整)的公差为-1的等差数列。
因此,在最终答案中直接加上y的个数 * y 以及除y后剩的因子和即可。但为了保证每个y只被算一次,我们应该让除y后剩余间的左端点l = max(a/y(向上取整), y)。同时,在y == l时,不要加两次y。计算量为1e6.
没理解的话可以结合代码思考,感觉代码比文字表达更清晰。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 ll a, b, ans; 45 int main() { 46 scanf("%lld%lld", &a, &b); 47 for (ll i = 1; i <= 1000000; ++i) { 48 ll x1 = (a - 1) / i + 1; 49 ll x2 = b / i; 50 if (x1 < i) x1 = i; 51 //printf("%lld %lld %lld\n", i, x1, x2); 52 if (i > b) break; 53 if (x1 > x2) continue; 54 if (x1 == i) ans -= x1; 55 ans += (x2 - x1 + 1) * i; 56 ans += (x2 - x1 + 1) * (x2 + x1) >> 1; 57 } 58 printf("%lld", ans); 59 return 0; 60 }
D
题意:定义一个序列 1, 1, 1, 1, 1, 1, ..., 2, 2, 2, 2, 2, 2, .....i, i, i, i, i, ..., n - 1 (每个数i连续出现n - i次), 求序列中间的那个数。
思路:对于每个数i,第一次出现的位置都可以O(1)求出来(等差数列求和),我们又可以求出序列总元素个数以及中间数的位置,因此二分判定就好了。O(logn)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 ll n; 45 ll cal(ll x) { 46 return (n + n - 1 - x) * x >> 1; 47 } 48 int main() { 49 scanf("%lld", &n); 50 ll cnt = ((n * (n - 1) >> 1) + 1) >> 1; 51 ll ans = 0, s = 0, e = n, mi; 52 while (s <= e) { 53 mi = s + e >> 1; 54 if (cal(mi) < cnt) { 55 s = (ans = mi) + 1; 56 } else { 57 e = mi - 1; 58 } 59 } 60 printf("%lld", ans + 1); 61 return 0; 62 }
E
题意:已知一个机器人的速度,起点终点都在x轴方向,中间有一些竖向的传送带,各个速度都已知, 判定一下机器人到终点的最短时间。
思路:对y轴移动距离列方程,把机器人速度分解,vy * L / vx = SUM(vi * li / vx)。vx可以约掉。因此O(1)求出vy, vx也可以求出。复杂度O(1)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n; 45 double x, V, v[105], l[105], r[105]; 46 int main() { 47 double cnt = 0; 48 scanf("%d%lf%lf", &n, &x, &V); 49 for (int i = 1; i <= n; ++i) { 50 scanf("%lf%lf%lf", &l[i], &r[i], &v[i]); 51 cnt += (r[i] - l[i]) * v[i]; 52 } 53 double vy = fabs(cnt / x); 54 if (vy >= V) { 55 puts("Too hard"); 56 return 0; 57 } else { 58 double vx = sqrt(V * V - vy * vy); 59 if (vx * 2 <= V + EPS) { 60 puts("Too hard"); 61 } else { 62 printf("%.3f\n", x / vx); 63 } 64 } 65 return 0; 66 }
F
题意:对于一个只有RB两种字符的字符串,求出一个子串使得‘R’, ‘B’两种字符数量的差值最大。
思路:可以将问题拆开。一种是求R的数量-B的数量最多,另一个是B的数量-R的数量最大。考虑每个单独的问题,比如要求R-B尽可能多,我们线性扫一遍,如果当前R的数量大于等于B,那么我们遇见R就加1, 遇见B就减1。
如果R比B少,那么我们为了使这个差值尽可能大,显然要舍弃之前选的那段序列,而从当前位置重新开始取。复杂度O(n)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n; 45 char s[100015]; 46 void solve(int &ma, int &l1, int &r1, char c) { 47 for (int i = 1, j = 1, cnt = 0, flag = 1; j <= n; ++j) { 48 if (!cnt) { 49 if (c == s[j]) { 50 ++cnt; 51 if (cnt > ma) { 52 l1 = r1 = j; 53 ma = cnt; 54 } 55 if (flag) { 56 i = j; 57 flag = 0; 58 } 59 } else { 60 flag = 1; 61 continue; 62 } 63 } else { 64 if (c == s[j]) { 65 ++cnt; 66 if (cnt > ma) { 67 r1 = j; 68 l1 = i; 69 ma = cnt; 70 } 71 } else { 72 --cnt; 73 } 74 } 75 } 76 } 77 int main() { 78 scanf("%s", s + 1); 79 n = strlen(s + 1); 80 int ma1 = 0, l1 = 0, r1 = 0, ma2 = 0, l2 = 0, r2 = 0; 81 solve(ma1, l1, r1, ‘B‘); 82 solve(ma2, l2, r2, ‘R‘); 83 int ans_l, ans_r; 84 if (ma1 > ma2 || (ma1 == ma2 && (l1 < l2 || (l1 == l2 && r1 < r2)))) { 85 ans_l = l1, ans_r = r1; 86 } else { 87 ans_l = l2, ans_r = r2; 88 } 89 printf("%d %d", ans_l, ans_r); 90 return 0; 91 }
G
题意:一个有向图中每条边都有一段区间,表示权限,只有x在这段区间内才可以经过这条边,求出所有能从起点走到终点的x。
思路:我们把所有的区间统一改成左闭右开的形式。把所有的时间段的端点提取出来并从小到大排序。然后考虑每个时间点ti,如果ti能从起点到达终点,那么[t(i), t(i + 1))这段区间内的所有时间点都可以到达终点,因为如果t(i)可以到达终点,那么它肯定不能只是一个时间段的右开端点,所以他至少是一个左闭端点,因此其向后取的那一小段时间段一定可取;如果t(i)不能到达,则显然只是一个右开端点,因此不取它后面的一段区间。O(mlogm + m*(m + n))。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n, m, k, s, t, ans; 45 struct edge { 46 int v, l, r; 47 edge () {} 48 edge (int v, int l, int r) : v(v), l(l), r(r) {} 49 }; 50 vector<edge> E[1015]; 51 vector<int> timestamps; 52 bool visit[1015]; 53 void dfs(int x, int timestamp) { 54 visit[x] = true; 55 for (int i = 0; i < E[x].size(); ++i) { 56 int v = E[x][i].v; 57 int l = E[x][i].l; 58 int r = E[x][i].r; 59 if (l <= timestamp && timestamp <= r && !visit[v]) { 60 dfs(v, timestamp); 61 } 62 } 63 } 64 int main() { 65 scanf("%d%d%d%d%d", &n, &m, &k, &s, &t); 66 while (m--) { 67 int a, b, c, d; 68 scanf("%d%d%d%d", &a, &b, &c, &d); 69 E[a].pb(edge(b, c, d)); 70 timestamps.pb(c); 71 timestamps.pb(d + 1); 72 } 73 sort(timestamps.begin(), timestamps.end()); 74 int number_Of_Timestamps = unique(timestamps.begin(), timestamps.end()) - timestamps.begin(); 75 for (int i = 0; i < number_Of_Timestamps - 1; ++i) { 76 int timestamp = timestamps[i]; 77 clr(visit, false); 78 dfs(s, timestamp); 79 if (visit[t]) { 80 ans += timestamps[i + 1] - timestamps[i]; 81 } 82 } 83 printf("%d", ans); 84 return 0; 85 }
H
题意:改变一个不均匀骰子的一个面的点数(可以为实数),使得其期望为3.5
思路:求出期望差值,除以概率最大的那个面就是改变的最小值。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 double p[11], sum, ma; 45 int main() { 46 for (int i = 1; i <= 6; ++i) { 47 scanf("%lf", &p[i]); 48 sum += p[i] * i; 49 ma = max(ma, p[i]); 50 } 51 printf("%.3f", fabs(sum - 3.5) / ma); 52 return 0; 53 }
I
题意:一个无限长字符串上一系列插入删除操作,问两组操作是否等价。
思路:用个链表暴力n*n模拟?(这题我还没写,这几天写完更新)
J
题意:一个n * m的方格上有‘B’, ‘R‘, ‘.‘分别表示黑色,红色,以及目前为空着。要求每个B左上角的所有块都必须为黑色,R右下角的所有块都必须为红色。
思路:你可以先n*n*m*m暴力利用所有已知的R,B信息把方格填充,这样左上角以及右下角都被确定,待处理的只有中间空的一部分,这个中间部分满足列数从左到右时,其相应待确定的行数单调递减。
因此,我们用dp[j][i]表示第j列第i行为此列最后一个黑色块,那么dp[j][i] = SUM(dp[j - 1][k]),其中k从i到n。复杂度O(n * n * m * m),可以优化到O(n*m)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n, m; 45 char mmp[35][35]; 46 ll dp[35][35]; 47 48 int main() { 49 scanf("%d%d", &n, &m); 50 for (int i = 1; i <= n; ++i) { 51 scanf("%s", mmp[i] + 1); 52 } 53 for (int i = 1; i <= n; ++i) { 54 for (int j = 1; j <= m; ++j) { 55 if (‘B‘ == mmp[i][j]) { 56 for (int k = 1; k <= i; ++k) { 57 for (int l = 1; l <= j; ++l) { 58 if (‘R‘ == mmp[k][l]) { 59 puts("0"); 60 return 0; 61 } 62 mmp[k][l] = ‘B‘; 63 } 64 } 65 } 66 if (‘R‘ == mmp[i][j]) { 67 for (int k = i; k <= n; ++k) { 68 for (int l = j; l <= m; ++l) { 69 if (‘B‘ == mmp[k][l]) { 70 puts("0"); 71 return 0; 72 } 73 mmp[k][l] = ‘R‘; 74 } 75 } 76 } 77 } 78 } 79 for (int i = n; ~i; --i) { 80 if (‘R‘ == mmp[i][1]) continue; 81 dp[i][1] = 1; 82 if (‘B‘ == mmp[i][1]) break; 83 } 84 for (int j = 2; j <= m; ++j) { 85 for (int i = n; ~i; --i) { 86 if (‘R‘ == mmp[i][j]) continue; 87 for (int k = i; k <= n; ++k) { 88 dp[i][j] += dp[k][j - 1]; 89 } 90 if (‘B‘ == mmp[i][j]) break; 91 } 92 } 93 /*for (int i = 0; i <= n; ++i) { 94 for (int j = 1; j <= m; ++j) { 95 printf("%d ", dp[i][j]); 96 } 97 puts(""); 98 }*/ 99 ll ans = 0; 100 for (int i = 0; i <= n; ++i) { 101 ans += dp[i][m]; 102 } 103 printf("%lld", ans); 104 return 0; 105 }
K
题意:美国国旗是有s个星,所有奇数行星数都为x, 所有偶数行星数都为y, x等于y或y + 1。
思路:枚举三种情况,(1) x == y (2) x == y + 1总行数为偶数 (3) x == y + 1总行数为奇数。最后排下序,复杂度O(S + sqrt(s) * logs)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 set<pii> ss; 45 int s; 46 int main() { 47 scanf("%d", &s); 48 for (int i = 2; i < s; ++i) { 49 if (s % i == 0) { 50 ss.insert(mp(i, i)); 51 } 52 } 53 for (int i = 2; i < s; ++i) { 54 if ((s - i) % (i + i - 1) == 0 || (s % (i + i - 1) == 0) ) { 55 ss.insert(mp(i, i - 1)); 56 } 57 } 58 printf("%d:\n", s); 59 for (set<pii>::iterator it = ss.begin(); it != ss.end(); ++it) { 60 int x = (*it).first, y = (*it).second; 61 printf("%d,%d\n", x, y); 62 } 63 return 0; 64 }
L
题意:已知x, k, p, 求x * n + k * p / n的最小值
思路:对号函数,因为n为整数,输出sqrt(k * p / x)左右两个整点对应函数值的最小值。O(1)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int k, p, x; 45 double cal(int n) { 46 return 1.0 * x * n + 1.0 * k * p / n; 47 } 48 int main() { 49 scanf("%d%d%d", &k, &p, &x); 50 int n = sqrt((k * p + 0.5) / x); 51 printf("%.3f\n", min(cal(n), cal(n + 1))); 52 return 0; 53 }
M
题意:给一个n,求出大于n中第一个不含0的数。
思路:从n+1开始枚举即可,复杂度O(n / 10)。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n; 45 bool ok(int x) { 46 while (x) { 47 if (x % 10 == 0) return false; 48 x /= 10; 49 } 50 return true; 51 } 52 int main() { 53 scanf("%d", &n); 54 for (int i = n + 1; ; ++i) { 55 if (ok(i)) { 56 printf("%d\n", i); 57 return 0; 58 } 59 } 60 61 return 0; 62 }