div3系列的打卡到这里就先告一段落了,以后的更新会是不定时的。最近的作业着实有点遭不过来,本来div3系列就是为了训练手速和见题,现在看来效果欠佳,CF的题目偏思维更多一些,你可以通过这写来练习思维,但是不要想着通过这些题目来查漏补缺,这里的题目并没有多少是可以让你套用模板的。但是,我的不足也的确找到了很多,尤其是DP太差了,而且答案的思路解释和代码用法对我而言也十分不错,总体还是有收获的。这个打卡停了之后,这个月陆陆续续会补上卡特兰数,斯特林数,二分和背包的博客(不分先后)。
(本场所有代码均为标程)
又是A题看不懂题目的一场,卡了一会儿,然后发现这个就是一个构造题,只要每次按照顺序输出26个字母即可。B题真的水,一点思路都不需要有,但是C题开始难度陡然增加,C题的切入点是要从长度n-1的两个串出发,先构造出原串,然后检查是否能满足题意即可,标程的multiset用的我一愣一愣的。D题思维型也很强,学到了这个骚操作,把高度直接转换成01串是因为,任何两个偶数之间都可以通过竖着放砖块达到一致,任何一个奇数高度都必须通过横着放砖块来达到一致,由于不求砖块的数量,所以直接按照01串处理,入栈,操作行云流水,佩服佩服。EF没看···十分抱歉,只贴代码。
A
#include
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
for (int i = 0; i < t; ++i) {
int n, k;
cin >> n >> k;
for (int j = 0; j < n; ++j) {
cout << char('a' + j % k);
}
cout << endl;
}
return 0;
}
B
#include
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a.begin(), a.end());
int res = 0;
for (int i = 0; i < n; i += 2) {
res += a[i + 1] - a[i];
}
cout << res << endl;
return 0;
}
C
#include
using namespace std;
int n;
vector<string> v;
string res;
bool check(const string &pref, const string &suf) {
string s = pref + suf.substr(n - 2);//拼接字符串
multiset<string> vv, sPref, sSuf;
for (int i = 0; i < n - 1; ++i) {
sPref.insert(s.substr(0, n - i - 1));//存入拼接后字符串的前缀
vv.insert(s.substr(0, n - i - 1));
sSuf.insert(s.substr(i + 1));//存入拼接后字符串的后缀
vv.insert(s.substr(i + 1));
}
if (vv == multiset<string>(v.begin(), v.end())) {//woc 还能这么比较的嘛 吓死宝宝了
for (int i = 0; i < 2 * n - 2; ++i) {
if (sPref.count(v[i])) {//这个count和erase用的真好 羡慕了
res += 'P';
sPref.erase(sPref.find(v[i]));
} else if (sSuf.count(v[i])) {
res += 'S';
sSuf.erase(sSuf.find(v[i]));
} else {
assert(false);
}
}
return true;
}
return false;
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> n;
v = vector<string>(2 * n - 2);//存储所有给出的前缀和后缀
vector<string> big;
for (int i = 0; i < 2 * n - 2; ++i) {
cin >> v[i];
if (int(v[i].size()) == n - 1) {//找出最大的两个 组成原串
big.push_back(v[i]);
}
}
if (check(big[0], big[1])) {
cout << res << endl;
} else {
check(big[1], big[0]);
cout << res << endl;
}
return 0;
}
D
#include
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int N = 200 * 1000 + 13;
int n;
int a[N];
int main() {
scanf("%d", &n);
forn(i, n){
scanf("%d", &a[i]);
a[i] &= 1;//直接转01串可还行
}
vector<int> st;//处理连续段的骚操作
//还有 vector直接当栈用我是真的佛 学到了
forn(i, n){
if (!st.empty() && a[i] == st.back())
st.pop_back();
else
st.push_back(a[i]);
}
puts(st.size() <= 1 ? "YES" : "NO");
return 0;
}
E
#include
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int N = 200 * 1000 + 13;
const int INF = 1000000000;
int n, m;
vector<int> g[N];
int bfs(int x, int dist[N]){
queue<int> q;
q.push(x);
dist[x] = 0;
int lst = -1;
while (!q.empty()){
int v = q.front();
q.pop();
lst = v;
for (auto u : g[v]) if (dist[u] > dist[v] + 1){
dist[u] = dist[v] + 1;
q.push(u);
}
}
return lst;
}
int distx[N], disty[N];
bool used[N];
vector<int> cur;
void dfs(int v){
used[v] = true;
cur.push_back(v);
for (auto u : g[v]) if (!used[u])
dfs(u);
}
int main() {
scanf("%d%d", &n, &m);
forn(i, m){
int v, u;
scanf("%d%d", &v, &u);
--v, --u;
g[v].push_back(u);
g[u].push_back(v);
}
forn(i, n) distx[i] = disty[i] = INF;
vector<pair<int, int>> comps;
forn(i, n) if (!used[i]){
cur.clear();
dfs(i);
int x = bfs(i, distx);
int y = bfs(x, disty);
for (auto v : cur) distx[v] = INF;
bfs(y, distx);
int d = disty[y], center;
for (auto v : cur) if (distx[v] == d / 2 && disty[v] == d - d / 2)
center = v;
comps.push_back({d, center});
}
vector<pair<int, int>> ans;
nth_element(comps.begin(), comps.end() - 1, comps.end());
forn(i, int(comps.size()) - 1){
g[comps[i].second].push_back(comps.back().second);
g[comps.back().second].push_back(comps[i].second);
ans.push_back({comps[i].second, comps.back().second});
}
forn(i, n) distx[i] = disty[i] = INF;
int y = bfs(bfs(comps.back().second, distx), disty);
printf("%d\n", disty[y]);
for (auto it : ans)
printf("%d %d\n", it.first + 1, it.second + 1);
return 0;
}
F
#include
using namespace std;
long long res, ans;
vector<int> a;
vector<long long> sum;
vector<vector<int>> g;
void dfs(int v, int p = -1, int h = 0) {
res += h * 1ll * a[v];
sum[v] = a[v];
for (auto to : g[v]) {
if (to == p) {
continue;
}
dfs(to, v, h + 1);
sum[v] += sum[to];
}
}
void go(int v, int p = -1) {
ans = max(ans, res);
for (auto to : g[v]) {
if (to == p) {
continue;
}
res -= sum[to];
sum[v] -= sum[to];
res += sum[v];
sum[to] += sum[v];
go(to, v);
sum[to] -= sum[v];
res -= sum[v];
sum[v] += sum[to];
res += sum[to];
}
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n;
cin >> n;
a = vector<int>(n);
sum = vector<long long>(n);
g = vector<vector<int>>(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
for (int i = 0; i < n - 1; ++i) {
int x, y;
cin >> x >> y;
--x, --y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs(0);
go(0);
cout << ans << endl;
return 0;
}