D.开关
从后往前扫一遍。
#include <bits/stdc++.h> using namespace std; string s; int main(){ int n; scanf("%d",&n); cin>>s; bool flag = 1; int ans = 0; for(int i=n-1;i>=0;i--){ if(flag && s[i]=='1' || !flag && s[i]=='0'){ flag=!flag; ans+=1; } } printf("%d\n",ans); }
E. 构造字符串
二分
#include <bits/stdc++.h> using namespace std; int num[26]; int main(){ int n; scanf("%d",&n); for(int i=0;i<26;i++){ scanf("%d",&num[i]); } long long l = 0, r = 1e15; while(l<r){ long long mid = (l+r+1)/2; //printf("%d %d\n",l,mid); long long now = 0; for(int i=0;i<26;i++){ now += num[i]/n; } if(now>=mid) l = mid; else r = mid-1; } printf("%lld\n",l); }
G. 字符串
字符串HASH+前缀和+map
#include <bits/stdc++.h> using namespace std; int cnt[30],sum[200001][30]; typedef unsigned long long ull; const ull base = 233333; ull Hash[200001],pw[200001]; string s, t; map <ull, bool> mp; int main(){ cin >> s; cin >> t; for(int i=0;i<s.size();i++){ cnt[s[i]-'a']++; } pw[0] = 1; for(int i=1;i<=t.size();i++){ pw[i] = pw[i-1]*base; Hash[i] = Hash[i-1]*base + t[i-1]; for(int j=0;j<26;j++){ sum[i][j] = sum[i-1][j]; } sum[i][t[i-1]-'a']+=1; } int ans = 0; for(int l=1;l<=t.size();l++){ int r = l+s.size()-1; if(r>t.size()) break; bool flag = true; for(int i=0;i<26;i++){ if(sum[r][i]-sum[l-1][i]!=cnt[i]) flag = false; } if(!flag) continue; ull hashvalue = Hash[r] - Hash[l-1]*pw[r-l+1]; if(mp.count(hashvalue)) continue; mp[hashvalue] = 1; ans++; } printf("%d\n",ans); }