把过去和现在的笔记记录也搬了过来,也算是给以后留个念想吧,想想一开始打acm就是图一乐,后来发现这游戏还挺上头的,也算是度过了一段电竞生涯(xs)
早些时候的笔记写的好中二,连我自己看着都羞耻。
不过,就喜欢这种羞耻的感觉。
收录的题目大部分是个人认为质量不错的题目,以DP为主,非DP的题目都用※进行了标识。
当然,有些题解思路本身也是源自其他人的,不过除非特殊标注,否则都是用的自己的代码。
题目大意:
1620C BA-String
题目大意:给你一个长度为N的字符串,包含a和,你可以将每个转换成(0-k)个’b’,现在要求你能得到的字典序第x大的字符串。
解:
看似非常简单,实际上就是一个进制问题,每一串连续的表示nk个单位,而一个单位的大小则是后一个串能表示的最大数量,可以用dp来记录也可以纯粹地用函数去计算,n只有2000,不用担心t的问题,求答案时将单位从大到小除一下取值就行。
问题在于,虽然题面说了x的大小不会大于1e18,但你的单位的大小却有可能超过1e18,超过1e18之后下场自然是溢出,溢出就会造成错误的判断,于是你需要用取对数的方法来判断你即将得到的单位是否超过1e18,但这依然不够,因为有可能你在判断溢出的过程中它就已经溢出了,所以建议是将乘区的两部分分别转化为double再去计算log10的值,log2应该也行。
Debug了好久,总之就是很sb,除了知道要判溢出以外什么都没学到。
本来不想专门写一篇的,结果还是写了……
代码
代码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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <algorithm> #include <utility> #include <vector> #include <istream> #include <map> #include <cmath> #include <cstring> #include <string> #define ll long long #define maxn 200005 #define mdl 998244353 #define clr(a,n) for(int i=0;i<n;i++)a[i]=0 using namespace std; ll dp[2005],seg[2005],ans[2005]; char a[2005],res[4000005];
int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); ll t; cin >> t; while (t--) { ll n, k, x; cin >> n >> k >> x; scanf("%s", a); ll xb = 0,tmp=0; for (ll i = 0; i < n; i++) { if (a[i] == '*') { tmp++; if (i == n - 1 || a[i + 1] == 'a') { seg[xb++] = tmp; tmp = 0; } } } dp[0] = 1; int ii = 0; for (ll i = 1; i <= xb; i++) { dp[i] = dp[i - 1] * (1+seg[xb - i]*k); ii = i; if (i<xb&&log10((double)dp[i])+log10((double)(1+seg[xb-i-1]*k))>=18) { ii++; break; } } ll xx = ii; x--; while (xx) { if (x < dp[xx-1]) { ans[xb - xx] = 0; } else { ans[xb - xx] = x / dp[xx - 1]; x -= x / dp[xx - 1] * dp[xx - 1]; } xx--; } ll stp = 0,sg=0; for (ll i = 0; i < n; i++) { if (a[i] == '*') { for (int j = 0; j < ans[sg]; j++) { res[stp++] = 'b'; } i += seg[sg] - 1; sg++; } else res[stp++] = 'a'; } for (ll i = 0; i < stp; i++) { printf("%c", res[i]); } printf("\n"); clr(ans, 2005); }
}
|
Copyright Notice: 此文章版权归EmiteInna所有,多看看吧。