Hitachi Vantara Programming Contest 2024(AtCoder Beginner Contest 368)

暑期最后一场了,abc368,时间断断续续做了ABCDF五题,先贴个比赛链接——ABC-contest368


目录

 A题

思路分析

代码实现

 B题

思路分析

代码实现

 C题

思路分析

代码实现

D题

思路分析

代码实现

 F题

思路分析

代码实现


 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来场吧,收获也是挺大的,开学有时间继续,加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值