前言
- E, F两题的代码参考来源均来自出题人的题解。
- 可以前去bilibili搜索牛客竞赛观看视频题解。
A-小红的字符串生成
思路:
- 枚举两种情况
以下是代码部分
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N = 100010;
using ll = long long;
void solve()
{
char a, b;
cin >> a >> b;
if(a != b)
{
cout << "4\n";
cout << a << endl;
cout << b << endl;
cout << a << b << endl;
cout << b << a << endl;
}
else
{
cout << "2\n";
cout << a << endl;
cout << a << b << endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t --)
solve();
return 0;
}
B-小红的非排列构造
思路:
- 首先暴力判断是否为排列
- 如果是排列,修改一个数即可。
- 如果不是排列则输出0
以下是代码部分
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N = 1e5 + 10;
using ll = long long;
int a[N];
void solve()
{
int n;
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
sort(a + 1, a + n + 1);
for(int i = 1; i < n; i ++)
if(a[i] == a[i + 1] || a[i] > n)
{
cout << "0\n";
return ;
}
if(a[n] > n)
{
cout << "0\n";
return ;
}
cout << "1\n1 99999999";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t --)
solve();
return 0;
}
C-小红的数字拆解
###思路:
- 贪心:遇到这一位数为偶数就拆解
- 注意排序方法即可
以下是代码部分
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N = 1e5 + 10;
using ll = long long;
int a[N];
string s;
bool cmp(string x, string y)
{
if(x.size() != y.size())
return x.size() < y.size();
else
return x < y;
}
void solve()
{
vector<string> v;
cin >> s;
int len = (int)s.size();
string temp;
for(int i = 0; i < len; i ++)
{
temp += s[i];
if(((s[i] - '0') & 1) == 0)
{
v.push_back(temp);
temp.clear();
}
}
sort(v.begin(), v.end(), cmp);
for(string i : v)
cout << i << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t --)
solve();
return 0;
}
D-小红的陡峭值
思路:
- 恭喜获得分类讨论大师称号
以下是代码部分
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
const int N = 1e5 + 10;
int a[N];
void solve()
{
int n;
cin >> n;
for(int i = 0; i < n; i ++) cin >> a[i];
//如果头和尾都不是0的特判
if(a[0] != 0 && a[n - 1] != 0)
if(abs(a[0] - a[n - 1]) != 1)
{
cout << "-1\n";
return ;
}
//记录最大值和最小值
int mi = INT_MAX, ma = 1;
for(int i = 0; i < n; i ++)
{
//记录最大值的位置和最小值的位置
if(a[i] == 0) continue;
ma = max(ma, a[i]);
mi = min(mi, a[i]);
}
vector<int> v1, v2;
//如果最大值和最小值的差值为1
if(ma - mi == 1)
{
for(int i = 0; i < n; i ++)
{
if(a[i] == 0) continue;
//如果值为最小值,则把坐标存入v1中
if(a[i] == mi) v1.push_back(i);
//如果值为最大值,则把坐标存入v2中
if(a[i] == ma) v2.push_back(i);
}
//如果最小值的最右边在最大值的最左边之前,则合法
if(v1.back() < v2[0])
{
//直接输出
int i;
for(i = 0; i <= v1.back(); i ++)
cout << mi << ' ';
for(; i < n; i ++)
cout << ma << ' ';
}
//如果最大值的最右边在最小值的最左边之前,则合法
else if(v2.back() < v1[0])
{
//直接输出
int i;
for(i = 0; i <= v2.back(); i ++)
cout << ma << ' ';
for(; i < n; i ++)
cout << mi << ' ';
}
else cout << -1;
}
//如果最大值等于最小值
else if(ma == mi)
{
//如果头为0
if(a[0] == 0)
{
cout << mi + 1 << ' ';
for(int i = 0; i < n - 1; i ++)
cout << mi << ' ';
}
//如果尾为0
else
{
for(int i = 0; i < n - 1; i ++)
cout << mi << ' ';
cout << mi + 1 << ' ';
}
}
//如果全是0
else if(mi > 1e9)
{
cout << "1 ";
for(int i = 0; i < n - 1; i ++)
cout << "2 ";
}
//都不是,输出-1
else cout << -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t --)
solve();
return 0;
}
E-小红的树形 dp
思路:
- 二分图
- d or p 各自只能在树的奇偶性相同的层级中:
- 比如d如果在奇数层, 为1 3 5 ……, 那么p只能在偶数层2 4 6……。反之亦然。
以下是代码部分
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
const int N = 1e5 + 10, M = 2 * N;
string s;
int dp[M];
vector<int> v[N];
//图的遍历
void dfs(int u, int fa, int p)
{
dp[u] = p;
for(int x : v[u])
{
if(x == fa) continue;
dfs(x, u, 1 - p);
}
}
void solve()
{
int n;
cin >> n >> s;
//建图
for(int i = 1; i < n; i ++)
{
int x, y;
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
//使下标保持一致
s = ' ' + s;
dfs(1, 0, 1);
set<int> d, p;
//存入d or p 的节点的层数的奇偶
for(int i = 1; i <= n ; i++)
{
if(s[i] == 'd') d.insert(dp[i]);
if(s[i] == 'p') p.insert(dp[i]);
}
//当d or p 有一种的奇偶性都有,那代表不成立
if(d.size() > 1 || p.size() > 1)
{
cout << -1;
return ;
}
//在都只有一种奇偶性的情况下,避免d or p 处于同一种奇偶
else if((d.size() == 1 && p.size() == 1) && *d.begin() == *p.begin())
{
cout << -1;
return ;
}
//当d在奇数层的时候输出
if(*d.begin() == 1)
for(int i = 1; i <= n; i ++)
{
if(dp[i] == 1) cout << 'd';
else cout << 'p';
}
//当p在奇偶层的时候的输出
else
for(int i = 1; i <= n; i ++)
{
if(dp[i] == 1) cout << 'p';
else cout << 'd';
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t --)
solve();
return 0;
}