====== 657div2 ====== ==== A. Acacius and String ==== **题意**:给定一个字符串,可以把?换成任意字符,使得一个给定的字符串只能出现一次, **题解**:暴力即可,考试时手滑了被卡了一个小时 string s; int n; string T = "abacaba"; bool check(string &a) { int cnt = 0; rep(i, 0, n - 7) { if (a.substr(i, 7) == T) cnt++; } return cnt == 1; } int main() { int t; sd(t); while (t--) { cin >> n >> s; int flag = 0; rep(i, 0, n - 7) { string ss = s; bool ok = 1; rep(j, 0, 6) { if (ss[i + j] != T[j] && ss[i + j] != '?') { ok = 0; break; } ss[i + j] = T[j]; } if (ok && check(ss)) { rep(j, 0, n - 1) { if (ss[j] == '?') ss[j] = 'z'; } puts("Yes"); flag = 1; cout << ss << endl; break; } } if (!flag) puts("No"); } return 0; } B. Dubious Cyrpto **题意:** 有三个整数 a,b,c 满足$l<=a,b,c<=r$还有一个整数$m = n*a+b-c$。n 是正整数。$给定l,r,m$求出$a,b,c$的一组可能值 **题解**: 可以求出$m-b+c$的范围,然后暴力枚举a,判断是否存在n即可。 #include #include #include #include using namespace std; typedef long long ll; int main() { int t; cin >> t; while(t--) { ll l, r, m; cin >> l >> r >> m; ll LL = max(0ll, m + l - r), RR = m + r - l; ll a; ll n; for (a = l; a <= r;a++) { ll tem = (LL / a) * a; if( tem >=LL && tem <= RR && LL/a!=0) { n = LL / a; break; } tem += a; if( tem >=LL && tem <= RR) { n = LL / a + 1; break; } } ll d = a * n - m; ll b, c; if(d <= 0) { b = r; c = d + b; } else { c = r; b = c - d; } cout << a << " " << b << ' ' << c << endl; } return 0; } ==== C. Choosing flowers ==== **题意**:有 m 种花,每种花第一次购买获益a,之后在购买购买获益b,问买n朵花,最大收益。 **题解**: 发现只有一种花会被购买2朵以及以上,否则必定获益相等于是也可转化为前一种情况,那只要枚举哪一种花购买多次即可。 #include using namespace std; #define pll pair pairx[100005]; long long sum[100005]; int upper(int l,int r,long long num) { int ans = -1; while (l <= r) { int mid = (l + r) >> 1; if (x[mid].first > num) { ans = mid; l = mid + 1; } else r = mid - 1; } return ans; } int main() { int t; cin >> t; while (t--) { int n, m; cin >> n >> m; int i; for (i = 0; i < m; i++) { cin >> x[i].first >> x[i].second; sum[i] = 0; } sort(x, x + m, greater>()); for (i = 0; i < m; i++) { //cout << x[i].first << ' ' << x[i].second << endl; if (i)sum[i] = x[i].first + sum[i - 1]; else sum[i] = x[i].first; } long long ans = 0; for (i = 0; i < m; i++) { int p = upper(0, m-1, x[i].second); if (p != -1) { ans = max(ans, sum[min(p, n-1)] + (p < i ? max(0, n - p - 2) * x[i].second + (n>p+1?x[i].first:0) : max(0, n - p-1) * x[i].second)); } else { ans = max(ans, (n-1) * x[i].second + x[i].first); } } long long ans2 = 0; for (i = 0; i < m && n; i++) { ans2 += x[i].first; n--; } cout << max(ans2, ans) << endl; } return 0; }