暑期最后一场了,abc368,时间断断续续做了ABCDF五题,先贴个比赛链接——ABC-contest368
目录
A题
思路分析
直接模拟,从jiangly那里学了一个rotate()
函数,之前没用过这个函数哈哈,挺好用的,贴个详解链接rotate()函数
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
using namespace std ;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
//int a[N];
PII p[N];
void solve()
{
int n,m;
cin >> n >> m;
vector<int> a(n);
for(int i = 0; i < n ;i++) cin >> a[i];
/* for(int i = n - m + 1; i <= n; i++) cout << a[i] << " ";
for(int i = 1; i <= n - m; i++) cout << a[i] << " "; */
rotate(a.begin() ,a.begin() + n - m , a.end());//下标必须从0开始
for(int i = 0; i < n; i++) cout << a[i] << " ";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t -- ) solve();
return 0;
}
B题
思路分析
直接模拟或者用大根堆维护,大根堆的特点是栈顶永远是最大元素。
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
using namespace std ;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
int a[N];
PII p[N];
bool check(int n,int a[])
{
int s = 0;
for(int i = 1; i <= n; i++)
{
if(a[i] > 0) s++;
}
if(s <= 1) return true;
return false;
}
void solve()
{
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
int j = 0;
while(++j)
{
sort(a + 1,a + n + 1,greater<int>());
/* for(int i = 1; i <= n; i++) cout << a[i] << " ";
cout << endl; */
a[1] -= 1;
a[2] -= 1;
if(check(n,a))
{
/* for(int i = 1; i <= n; i++) cout << a[i] << " ";
cout << endl; */
cout << j << endl;
return;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t -- ) solve();
return 0;
}
/*void solve()
{
int n;
cin >> n;
priority_queue<int> q;
for(int i = 1; i <= n; i++)
{
int x;
cin >> x;
q.push(x);
}
int res = 0;
while(q.size() > 1)
{
int k1 = q.top();
q.pop();
int k2 = q.top();
q.pop();
if(k1 > 1) q.push(k1 - 1);
if(k2 > 1) q.push(k2 - 1);
res ++;
}
cout << res << endl;
}*/
C题
思路分析
每隔三秒一个数会下降5,所以直接找到这个规律模拟就行。
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
using namespace std ;
typedef pair<int,int> PII;
const int N = 2e5 + 10;
int a[N];
PII p[N];
void solve()
{
int n;
cin >> n;
int cnt = 0;
for(int i = 1; i <= n; i++)
{
int x;
cin >> x;
//规律:每隔三秒减少5
cnt += x / 5 * 3;
x %= 5;
// cout << cnt << " " << x << endl;
while(x > 0)
{
++cnt;
if(cnt % 3 == 0) x -= 3;
else x -= 1;
}
}
cout << cnt << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t -- ) solve();
return 0;
}
D题
思路分析
树的dfs,找到任意一个要保留的特殊点作为树的根节点,详细的不太好描述,可画图结合代码
理解,本题bfs写法挺重要的,有关树的问题经常这样写,应该记住这种模版写法——
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
using namespace std ;
typedef pair<int,int> PII;
const int N = 2e5 + 10;
int a[N];
PII p[N];
vector<int> G[N];
int dfs(int now, int lst)//当前节点的位置和前一个位置
{
int cnt = 0;//以now为根节点的子树需要保留的数量
for(int i = 0; i < G[now].size(); i++)
{
int m = G[now][i];
if(m == lst) continue;
cnt += dfs(m , now);//子树所需要保留的数量(不包含根节点)
}
if(cnt || a[now]) cnt++;//如果子树需要保留的不为0或者自身需要保留则加上自身
return cnt;
}
void solve()
{
int n,k;
cin >> n >> k;
for(int i = 1; i < n; i++)
{
int u,v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
int st;//选一个特殊点做根节点
for(int i = 1; i <= k; i++)
{
int x;
cin >> x;
a[x] = 1;
st = x;
}
cout << dfs(st,-1) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t -- ) solve();
return 0;
}
F题
思路分析
Nim博弈游戏问题,需要用到sg函数(虽然笔者现在还真不理解sg这种博弈问题wuwu),先把代码补上吧。
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n;
cin >> n;
std::vector<int> a(n + 1);
std::vector<set<int>> S(100005);
std::vector<int> sg(100005, 0);
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= 100000; i ++) {
for (int j = 0; j <= 100005; j ++)
if (S[i].count(j)) sg[i] ++;
else break;
for (int j = i + i; j <= 100000; j += i)
S[j].insert(sg[i]);
}
int res = 0;
for (int i = 1; i <= n; i ++) {
res ^= sg[a[i]];
}
if (!res) cout << "Bruno" << endl;
else cout << "Anna" << endl;
return 0;
}
牛客还缺两场没补完,明天白天有时间就补,没时间就等开学吧,这个月一直在打线上赛,20天左右累计打了20来场吧,收获也是挺大的,开学有时间继续,加油!!!