img
牛客周赛 Round 38
A
直接写即可
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 #include <bits/stdc++.h> #define x first #define y second #define pb push_back using namespace std;const int N = 2e5 + 10 ;const int P = 1e9 + 7 , INF = 0x3f3f3f3f ;typedef pair<int , int > PII;typedef pair<double , double > PDD;typedef long long LL;void solve () { int x; cin >> x; int cnt = 0 ; while (x % 10 != 0 ) x ++, cnt ++; cout << cnt; } int main () { int T = 1 ; while (T -- ) { solve (); } return 0 ; }
B
9的倍数加起来一定是9的倍数
一个性质来的
可以自己小小的模拟一下
因此只需要O(n)暴力枚举一遍就行了
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 #include <bits/stdc++.h> #define x first #define y second #define pb push_back using namespace std;const int N = 2e5 + 10 ;const int P = 1e9 + 7 , INF = 0x3f3f3f3f ;typedef pair<int , int > PII;typedef pair<double , double > PDD;typedef long long LL;void solve () { string s; cin >> s; LL sum = 0 , ans = 0 ; for (auto t : s) sum += t - '0' ; for (int i = s.size () - 1 ; i >= 0 ; i -- ) { if (sum % 9 == 0 ) ans ++; sum -= s[i] - '0' ; } cout << ans; } int main () { int T = 1 ; while (T -- ) { solve (); } return 0 ; }
C
还是有一个性质就是,连续字符串的回文子串个数有这么多个i*(i-1)/2,注意是去除了1的
用尽可能长的连续的相同字符取构造即可
直接进行构造即可。
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 #include <bits/stdc++.h> #define x first #define y second #define pb push_back using namespace std;const int N = 2e5 + 10 ;const int P = 1e9 + 7 , INF = 0x3f3f3f3f ;typedef pair<int , int > PII;typedef pair<double , double > PDD;typedef long long LL;void solve () { LL n, k; cin >> n >> k; char c = 'd' ; int cnt = 0 ; for (LL i = n; i >= 2 ; i -- ) { LL t = i * (i - 1 ) / 2 ; while (k >= t) { k -= t; for (LL j = 0 ; j < i; j ++ ) cout << c, cnt ++; c ++; } } string s = "abc" ; for (; cnt < n; cnt ++ ) cout << s[cnt % 3 ]; } int main () { int T = 1 ; while (T -- ) { solve (); } return 0 ; }
D
如果数组中所有相邻点间隔的最大值等于k,则答案为0
如果小于k,则答案为1,因为可以在任意两个点之间加上一个数,是其与较小的数的差值等于k
如果大于k,则需要计算每一个间隔大于k对答案的贡献
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 #include <iostream> #include <vector> int main () { int n, k; std::cin >> n >> k; std::vector<int > nums (n) ; for (int i = 0 ; i < n; ++i) { std::cin >> nums[i]; } long long res = 0 ; long long max_diff = 0 ; for (int i = 1 ; i < n; ++i) { long long d = abs (nums[i] - nums[i - 1 ]); max_diff = std::max (max_diff, d); res += std::max ((d - 1 ) / k, 0LL ); } if (max_diff < k) { res = 1 ; } std::cout << res << std::endl; }
E
枚举a,然后再枚举a的因子,注意因子有j,和a/j两个,分别去找即可
注意公比等于1的情况
还有一点就是有一个函数的运用
找到其中最大的元素
1 int res = *max_element (f.begin (), f.end ());
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 #include <bits/stdc++.h> #define x first #define y second #define pb push_back using namespace std;const int N = 2e5 + 10 ;const int P = 1e9 + 7 , INF = 0x3f3f3f3f ;typedef pair<int , int > PII;typedef pair<double , double > PDD;typedef long long LL;void solve () { int n; cin >> n; vector<int > a (n + 1 ) ; vector<int > f (N) ; for (int i = 1 ; i <= n; i ++ ) cin >> a[i], f[a[i]] ++; sort (a.begin () + 1 , a.end ()); int res = *max_element (f.begin (), f.end ()); for (int i = 1 ; i <= n; i ++ ) { int x = a[i]; for (int j = 1 ; j <= sqrt (x); j ++ ) { if (x % j == 0 ) { int t = x, cnt = 1 ; while (t % j == 0 && f[t / j] && j > 1 ) t /= j, cnt ++; res = max (res, cnt); if (x / j != j) { t = x, cnt = 1 ; while (t % (x / j) == 0 && f[t / (x / j)]) t /= (x / j), cnt ++; res = max (res, cnt); } } } res = max (res, f[x]); } cout << res; } int main () { int T = 1 ; while (T -- ) { solve (); } return 0 ; }
F
最容易达到的回文子序列应该是长度为3的。
换句话说,假如我们有一个长度为>=4的回文子序列,一定可以从中抽出一个形如“aba”型的子序列(b可以等于a)。
那么,这道问题就可以转化成[l,r]是否存在这样的字符串即可,用lst记录最近的左端点,由于要隔着一个数字,就贪心的把\(a_{i-1}\) 去了。
再递推一下lst[i]=max(lst[i],lst[i-1])4
然后lst[r]>l就一定会有解
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 #include <bits/stdc++.h> using namespace std;#define pii pair<int, int> #define pdd pair<double, double> #define pll pair<ll, ll> #define endl '\n' typedef long long ll;inline void solve () { int n, q; cin >> n >> q; vector<int > a (n+1 ) ; for (int i=1 ; i<=n; i++) cin >> a[i]; unordered_map<int , int > mp; vector<int > lst (n+1 ) ; for (int i=1 ; i<=n; i++) { if (mp.count (a[i])) lst[i] = mp[a[i]]; lst[i] = max (lst[i], lst[i-1 ]); if (i >= 2 ) mp[a[i-1 ]] = i-1 ; } while (q --) { int l, r; cin >> l >> r; if (lst[r] >= l) cout << "YES" << endl; else cout << "NO" << endl; } } int main () { cout << fixed << setprecision (10 ); ios::sync_with_stdio (false ); cin.tie (0 );cout.tie (0 ); int t; t = 1 ; while (t --) solve (); return 0 ; }
G
本题考察为树状数组+双指针
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 56 57 58 59 60 #include <bits/stdc++.h> using namespace std;using ll=long long ;#define int long long struct BIT { int n; vector<int > tr; BIT (int _n) : n (_n), tr (n + 10 ) {} int lowbit (int x) {return x & (- x);}; void add (int x, int y) { for (int pos = x; pos < n; pos += lowbit (pos)){ tr[pos] += y; } } ll query (ll x) { ll res = 0 ; for (int pos = x; pos; pos -= lowbit (pos)){ res += tr[pos]; } return res; } ll query (ll l, ll r) { return query (r) - query (l - 1 ); } }; void solve () { int n, k; cin >> n >> k; vector<ll> a (n + 1 ) ; for (int i = 1 ; i <= n; i ++) cin >> a[i]; BIT bit1 (1e6 + 10 ) ; BIT bit2 (1e6 + 10 ) ; ll sum = 0 ; for (int i = n; i >= 1 ; i --){ bit1.add (a[i], 1 ); sum += bit1.query (a[i] - 1 ); } int ans = (sum >= k); for (int i = 1 , j = 1 ; i <= n; i ++){ bit1.add (a[i], -1 ); sum -= bit1.query (a[i] - 1 ); sum -= bit2.query (a[i] + 1 , 1e6 ); while (j <= i && sum < k){ bit2.add (a[j], 1 ); sum += bit1.query (a[j] - 1 ); sum += bit2.query (a[j] + 1 , 1e6 ); j ++; } ans += (i - j + 1 ); } cout << ans << '\n' ; } signed main () {solve (); return 0 ; }