题意
给定字符串s,任意次交换长度为奇数的连续子串,求最小字典序
思路
通过交换区间[l,r]和交换[l+1,r-1]可以实现 同奇偶位 的 数字互换
用两个vector存数字,sort后输出即可
代码
void solve()
{
string s;
cin >> s;
vector<int> odd;
vector<int> even;
int l = s.length();
for (int i = 0; i < l; i++)
{
if (i % 2)
even.push_back(s[i] - '0');
else
odd.push_back(s[i] - '0');
}
sort(odd.begin(), odd.end());
sort(even.begin(), even.end());
for (int i = 0; i < odd.size(); i++)
{
cout << odd[i];
if (i < even.size())
cout << even[i];
}
cout << endl;
}
题意
一个包含(0,0)到(n,n)的坐标系,最少绘制几条线能覆盖除(0,0)外的所有点
代码
void solve()
{
int n;
cin >> n;
cout << 2 * n << endl;
}
题意
给定一棵树,求最多剩余节点数,使得每个节点的度小于等于1
思路
树状dp
代码
const int N = 5 * 1e5 + 5; // N点数
const int M = 2 * N; // M边数
int n, m; //输入点数、边数
int idx; //实际边数
int head[N]; //以i为起点的第一条边的下标
int f[N][2][2];
struct Edge
{
int to, next, w;
} edge[M]; // to边的终点 w边的权值 next同起点下一条边的下标
void add(int u, int v, int w)
{
edge[idx].to = v;
edge[idx].next = head[u];
edge[idx].w = w;
head[u] = idx++;
}
void dfs(int u, int fa)
{
f[u][1][0] = f[u][0][0] = 0;
f[u][1][1] = f[u][0][1] = 1;
int sum = 0;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int to = edge[i].to;
if (to == fa)
continue;
dfs(to, u);
f[u][0][0] += max(f[to][0][1], f[to][0][0]);
sum += f[to][1][0];
f[u][1][0] += max(f[to][0][1], f[to][0][0]);
f[u][1][1] += f[to][1][0];
}
f[u][0][1] += sum;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int to = edge[i].to;
if (to == fa)
continue;
f[u][0][1] = max(f[u][0][1], 1 + sum - f[to][1][0] + f[to][1][1]);
}
}
void solve()
{
cin >> n;
memset(head, -1, sizeof head);
idx = 0;
for (int i = 1; i < n; i++)
{
int u, v;
cin >> u >> v;
add(u, v, 0);
add(v, u, 0);
}
dfs(1, -1);
ll ans = max(max(f[1][0][0], f[1][0][1]), max(f[1][1][1], f[1][1][0]));
cout << ans << endl;
}
题意
给定n*m的矩形,允许横向竖向切分,需保证所有小矩形体积大于等于k,求最多切分次数、
思路
枚举i*h的小矩形
代码
void solve()
{
int n, m, k;
cin >> n >> m >> k;
int m_ = max(m, n), n_ = min(m, n);
int res = 0;
for (int i = 1; i <= m; i++)
{
int h = ceil(k * 1.0 / i);
if (h > n)
continue;
int cnt = m / i - 1 + n / h - 1;
res = max(res, cnt);
}
cout << res << endl;
}