世间情动,不过盛夏白瓷梅子汤,碎冰碰壁当啷响。
世间情劫,不过三九黑瓦黄连鲜,糖心低落苦作言。
世间执念,不过隆冬弱水千层冰,斧砸锹凿不能移。
世间情深,不过群星点点衬孤月,黑夜相随永相明。
世间温柔,不过是芳春柳摇染花香,槐序蝉鸣入深巷,白茂叶落醉故乡。
图片
牛客周赛 Round 14
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 32 33 34 35 36 37 38 39 40 41 42 #include <bits/stdc++.h> using namespace std;vector<char >k; int t,ans;int main () { int n; cin>>n; char a; for (int i=0 ;i<n;i++) { cin>>a; k.push_back (a); } while (k.size ()>1 ) { t=0 ; if (k[0 ]==k[k.size ()-1 ]) { t=1 ; k.erase (k.begin ()); k.pop_back (); ans+=2 ; } else for (int i=1 ;i<k.size ();i++) { if (k[i]==k[i-1 ]) { t=1 ; k.erase (k.begin ()+i); k.erase (k.begin ()+i-1 ); ans+=2 ; break ; } } if (t==0 ) break ; } cout<<ans; return 0 ; }
B
大就要除,不能整除直接跳
小就要乘法,直接乘法
最后判断
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 #include <iostream> using namespace std;int main () { int t; cin >> t; while (t--) { int x, y; cin >> x >> y; int ans = 0 ; while (x != y) { if (x < y) { x *= 5 ; ans++; } else if (x > y && x % 6 == 0 ) { x /= 6 ; ans++; } else break ; } if (x == y) { cout << ans << endl; } else { cout << -1 << endl; } } }
当然也有一种相对来说比较暴力的
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 <bits/stdc++.h> using namespace std;int main () { map<double ,int >k; for (int i=0 ;i<=100 ;i++) for (int j=0 ;j<=100 ;j++) { k[double (pow (5 ,i)/(pow (6 ,j)*1.0 ))]=i+j; } int n;cin>>n; while (n--) { int a,b; cin>>a>>b; if (a==b) cout<<"0" <<endl; else { double c; c=double (b/(a*1.0 )); if (k[c]) cout<<k[c]<<endl; else cout<<"-1" <<endl; } } }
C
前缀和+二分
前缀和体现在26的字母的统计上
实际上也满足了单调递增的关系,因此可以用二分枚举左端点求右边界
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 #include <bits/stdc++.h> #define endl "\n" #define int long long using namespace std; const int N = 200010 ; int pre[N][30 ]; char s[N]; int n,l,r; int ans; int find (int sta,int t) { int l = sta - 1 ,r = n; while (l < r){ int mid = l + r + 1 >> 1 ; int cnt = 0 ; for (int i = 0 ;i < 26 ;i ++ ){ if (pre[mid][i] - pre[sta - 1 ][i] > 0 ) cnt ++; } if (cnt <= t) l = mid; else r = mid - 1 ; } return l; } signed main () { cin >> n >> l >> r; cin >> s + 1 ; for (int i = 1 ;i <= n;i ++ ){ for (int j = 0 ;j < 26 ;j ++ ) pre[i][j] = pre[i - 1 ][j] + (j == (s[i] - 'a' )); } for (int i = 1 ;i <= n;i ++ ){ ans += find (i,r) - find (i,l - 1 ); } cout << ans << endl; return 0 ; }
双指针也可以
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 #include <bits/stdc++.h> #define int long long using namespace std;signed main () { cin.tie (0 ) -> sync_with_stdio (0 ); int n, l, r; string str; cin >> n >> l >> r >> str; auto get = [&](int k) { map<char , int > mp; int res = 0 ; for (int r = 0 , l = 0 ; r < n; r ++) { mp[str[r]] ++; while (l <= r && mp.size () > k) { mp[str[l]] --; if (mp.count (str[l]) && !mp[str[l]]) { mp.erase (str[l]); } l ++; } res += r - l + 1 ; } return res; }; cout << get (r) - get (l - 1 ) << "\n" ; }
D
看数据->数学题
一个字符串的权值为:长度为3的回文子串 的数量
求长度为n的、仅由小写字母组成的所有字符串的权值之和。
从中不难看出,所求结果为:
$ = (n - 2) ^{(n - 1)} (10^9 + 7) $
通过模拟几组情况可以验证这一公式的正确性。
由于数据n的范围最大是\(10^{12}\) ,用暴力的方法一定会超时,所以要采用快速幂算法进行幂运算
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 #include <bits/stdc++.h> using namespace std;typedef long long LL;const int N=1e9 +7 ;void solve (LL n) { LL a=26 ; LL res=1 ; LL k=n-1 ; while (k) { if (k&1 ) res=(res*a)%N; k>>=1 ; a=(a*a)%N; } res=res%N; cout<<((n-2 )%N*res)%N<<endl; } int main () { LL n;cin>>n; if (n<3 ) { cout<<"0" <<endl; return 0 ; } solve (n); return 0 ; }
img