Codeforces Round #785 (Div. 2) A-C
Problem A
题意问给一个长度为2的小写字符串,字符串从ab开始,然后第一个位置和第二个位置上的字符不能相等,问按照这个方式排序,给出的字符串是第几个
然后这道题首先分情况讨论,首先题意可知每一个字符打头的有25个,然后如果当前第二个字符大于第一个字符,证明有skip 1,所以-1,否则 + 1
不难
#include <bits/stdc++.h> using namespace std; constexpr int limit = (400000 + 5);//防止溢出 #define INF 0x3f3f3f3f #define inf 0x3f3f3f3f3f #define lowbit(i) i&(-i)//一步两步 #define EPS 1e-9 #define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0); #define ff(a) printf("%d\n",a ); #define pi(a, b) pair<a,b> #define rep(i, a, b) for(ll i = a; i <= b ; ++i) #define per(i, a, b) for(ll i = b ; i >= a ; --i) #define MOD 998244353 #define traverse(u) for(int i = head[u]; ~i ; i = edge[i].nxt) #define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin) #define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout) typedef long long ll; typedef unsigned long long ull; char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf; inline ll read() { #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) ll sign = 1, x = 0; char s = getchar(); while (s > '9' || s < '0') { if (s == '-')sign = -1; s = getchar(); } while (s >= '0' && s <= '9') { x = (x << 3) + (x << 1) + s - '0'; s = getchar(); } return x * sign; #undef getchar }//快读 void print(ll x) { if (x / 10) print(x / 10); *O++ = x % 10 + '0'; } void write(ll x, char c = 't') { if (x < 0)putchar('-'), x = -x; print(x); if (!isalpha(c))*O++ = c; fwrite(obuf, O - obuf, 1, stdout); O = obuf; } int n,m; int a[limit]; int sum[limit]; void solve(){ string str; cin>>str; n = str.size(); str = " " + str; rep(i,1,n){ a[i] = str[i] - 'a' + 1; sum[i] = sum[i - 1] + a[i]; // cout<<a[i]<<" "; } if(n == 1){ cout<<"Bob"<<" "<<str[1] - 'a' + 1<<endl; return; }else if(n & 1){ int maxx = max(sum[n] - sum[1], sum[n - 1]); cout<<"Alice"<<" "<<abs((sum[n] - maxx) - maxx)<<endl; }else{ cout<<"Alice"<<" "<<sum[n]<<endl; } }; int32_t main() { #ifdef LOCAL FOPEN; // FOUT; #endif FASTIO int kase; cin>>kase; while (kase--) solve(); cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n"; return 0; }
Problem B
给一个字符串,然后要求任意一个子段内的最多出现的字符频率和最少出现的字符频率不能大于1,这个字符指的是在这个字符串出现过的
那么这个问题其实很好搞,观察样例,我们发现这个违反规则的样例一般是出现在两个相同字符打头的区间的,刚开始想的是找这样的区间
所以可以用一个数组维护当前index左边第一个和当前位置相同的位置,或者干脆把所有下标按照当前字符存一下,然后跑一下判断,看看所有字符是不是出现在了区间里面,如果不是,说明肯定不行,输出no
#include <bits/stdc++.h> using namespace std; constexpr int limit = (400000 + 5);//防止溢出 #define INF 0x3f3f3f3f #define inf 0x3f3f3f3f3f #define lowbit(i) i&(-i)//一步两步 #define EPS 1e-9 #define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0); #define ff(a) printf("%d\n",a ); #define pi(a, b) pair<a,b> #define rep(i, a, b) for(ll i = a; i <= b ; ++i) #define per(i, a, b) for(ll i = b ; i >= a ; --i) #define MOD 998244353 #define traverse(u) for(int i = head[u]; ~i ; i = edge[i].nxt) #define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin) #define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout) typedef long long ll; typedef unsigned long long ull; char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf; inline ll read() { #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) ll sign = 1, x = 0; char s = getchar(); while (s > '9' || s < '0') { if (s == '-')sign = -1; s = getchar(); } while (s >= '0' && s <= '9') { x = (x << 3) + (x << 1) + s - '0'; s = getchar(); } return x * sign; #undef getchar }//快读 void print(ll x) { if (x / 10) print(x / 10); *O++ = x % 10 + '0'; } void write(ll x, char c = 't') { if (x < 0)putchar('-'), x = -x; print(x); if (!isalpha(c))*O++ = c; fwrite(obuf, O - obuf, 1, stdout); O = obuf; } int n,m; int a[limit]; int sum[limit][30]; vector<int>g[limit]; void solve(){ string str; cin>>str; n = str.size(); auto s = set<char>{str.begin(), str.end()}; str = " " + str; rep(i,0,26)g[i].clear(); rep(i,1,n){ rep(j,0,25){ sum[i][j] = sum[i - 1][j] + (str[i] - 'a' == j); } } map<char, int>mp; rep(i,1,n){ mp[str[i]]++; g[str[i] - 'a'].push_back(i); } rep(i,0,25){ if(g[i].size() <= 1)continue; rep(j, 1, g[i].size() - 1){ int l = g[i][j - 1]; int r = g[i][j]; set<char>st; rep(h,l + 1, r){ st.insert(str[h]); } if(st.size() != mp.size()){ // cout<<str<<" "<<l<<" "<<r<<endl; cout<<"No"<<endl; return; } } } cout<<"Yes"<<endl; }; int32_t main() { #ifdef LOCAL FOPEN; // FOUT; #endif FASTIO int kase; cin>>kase; while (kase--) solve(); cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n"; return 0; }
Problem C
这个问题就是问一个数字只用自身为回文的数字表示,有多少种方式分解
这个问题,一眼想到了著名入门题“简单的整数划分问题”,然后跑了下前40000个数字,发现只有498个自身为回文的数字(暗藏玄只因),所以可以开下
处理手法类似,但是记得这个dp一定要预处理,或者记忆化,每次跑dp的话会tle
#include <bits/stdc++.h> using namespace std; constexpr int limit = (400000 + 5);//防止溢出 #define INF 0x3f3f3f3f #define inf 0x3f3f3f3f3f #define lowbit(i) i&(-i)//一步两步 #define EPS 1e-9 #define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0); #define ff(a) printf("%d\n",a ); #define pi(a, b) pair<a,b> #define rep(i, a, b) for(ll i = a; i <= b ; ++i) #define per(i, a, b) for(ll i = b ; i >= a ; --i) #define MOD 998244353 #define traverse(u) for(int i = head[u]; ~i ; i = edge[i].nxt) #define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin) #define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout) typedef long long ll; typedef unsigned long long ull; char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf; inline ll read() { #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) ll sign = 1, x = 0; char s = getchar(); while (s > '9' || s < '0') { if (s == '-')sign = -1; s = getchar(); } while (s >= '0' && s <= '9') { x = (x << 3) + (x << 1) + s - '0'; s = getchar(); } return x * sign; #undef getchar }//快读 void print(ll x) { if (x / 10) print(x / 10); *O++ = x % 10 + '0'; } void write(ll x, char c = 't') { if (x < 0)putchar('-'), x = -x; print(x); if (!isalpha(c))*O++ = c; fwrite(obuf, O - obuf, 1, stdout); O = obuf; } int n,m; int a[limit]; bool isPalindrome(int x){ int tmp = x; int sum = 0; while(tmp){ sum = sum * 10 + tmp % 10; tmp /= 10; } return sum == x; } int tot; ll dp[40005][501]; const ll mod = 1e9 + 7; void init(){ n = 4e4; tot = 0; rep(i,1,n){ if(isPalindrome(i)){ a[++tot] = i; } } rep(i,1,tot){ dp[0][i] = 1; } rep(i,1,n){ rep(j,1,tot){ if(i - a[j] >= 0){ dp[i][j] = (dp[i][j - 1] + dp[i - a[j]][j]) % mod; }else{ dp[i][j] = dp[i][j - 1] % mod; } } } } void solve(){ cin>>n; cout<<(1ll * dp[n][tot]) % mod<<endl; }; int32_t main() { #ifdef LOCAL FOPEN; // FOUT; #endif FASTIO init(); int kase; cin>>kase; while (kase--) solve(); cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n"; return 0; }
D有点头绪,但是因为前两题莫名wa2所以没时间做了,回去研究下
天才选手zerol的主页:https://zerol.me/
|
WeepingDemon的个人主页:https://weepingdemon.gitee.io/blog/