2024黑龙江CCPC

2024黑龙江省赛

B. String

  • 思路:栈模拟
  • 代码:
/*
* @Author: 	Hfuubigstrength
* @email:	2854614012@qq.com
* @Date:   2024-05-28 23:32:45
*/
#include <bits/stdc++.h>
//#define int long long
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define debug(a) cout<<#a<<"="<<a<<endl;
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()
using namespace std;

string s;
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> s;
	stack<char>stk;
	for(auto it : s){
		stk.push(it);
		if(stk.size() >= 3){
			char a = stk.top(); stk.pop();
			char b = stk.top(); stk.pop();
			char c = stk.top(); stk.pop();
			if(!(a == b && b == c)){
				stk.push(c);stk.push(b);stk.push(a);
			}
		}
	}
	string ans;
	while(stk.size()){
		ans += stk.top();
		stk.pop();
	}
	reverse(all(ans));
	if(!ans.size()) cout << "NAN";
	else cout << ans;
	return 0;
}

D. Card Game

  • 思路:贪心,把A从大到小排序,把B不为-1的从小到大排序,按顺序出牌,这种方法最优
  • 代码:
/*
* @Author: 	Hfuubigstrength
* @email:	2854614012@qq.com
* @Date:   2024-05-28 23:42:10
*/
#include <bits/stdc++.h>
// #define int long long
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define debug(a) cout<<#a<<"="<<a<<endl;
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()
using namespace std;

const int N = 100010;
int a[N], b[N], ah, bh, n;

void solve(){
	cin >> n >> ah >> bh;
	for(int i = 1; i <= n; i ++ ) cin >> a[i];
	vector<int>bb;
	int cntb = 0;
	for(int i = 1; i <= n; i ++ ){
		cin >> b[i];
		if(b[i] != -1) bb.pb(b[i]);
		else cntb ++;
	} 
	sort(all(bb));
	while(cntb -- ){
		bb.pb(-1);
	}
	sort(a + 1, a + 1 + n, greater<int>());
	for(int i = 1; i <= n; i ++ ){
		if(bb[i - 1] >= 0 && a[i] != -1) ah -= bb[i - 1];
		if(a[i] >= 0 && bb[i - 1] != -1) bh -= a[i];
		if(ah > 0 && bh <= 0){
			cout << "yes\n";
			return;
		}
		if(ah <= 0){
			cout << "no\n";
			return;
		}
	}
	cout << "no\n";
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);
	int tt = 1;
	cin >> tt;
	while(tt -- ){
		solve();
	}
	return 0;
}

F. Photography

  • 思路 :先预处理每一个点最大的三个邻接点,存下标。然后暴力枚举每两条边,如果能形成一条链,就从链的两端进行拓展出最大的那个点,这是处理长度大于3的情况。还要注意考虑长度为1, 2的情况。这题有孤点。
/*
* @Author: 	Hfuubigstrength
* @email:	2854614012@qq.com
* @Date:   2024-05-29 03:30:40
*/
#include <bits/stdc++.h>
//#define int long long
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define debug(a) cout<<#a<<"="<<a<<endl;
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()
using namespace std;
 
const int N = 10010;
int a[N], big[N][3];
int n, m, ans, now;
vector<PII>q[N];
vector<PII>edges;	

int work(int same1, int same2, int diff1, int diff2){
	int four = -1;
	int now = a[same1] + a[diff1] + a[diff2];
	bool f = 1;
	if(big[diff1][0] == same1 || big[diff1][0] == diff2 || big[diff1][0] == -1){
		if(big[diff1][1] == same1 || big[diff1][1] == diff2 || big[diff1][1] == -1){
			if(big[diff1][2] == -1 || big[diff1][2] == diff2 || big[diff1][2] == same1){
				f = 0;
			}else now += a[big[diff1][2]], four = big[diff1][2];
		}else now += a[big[diff1][1]], four = big[diff1][1];
	}else now += a[big[diff1][0]], four = big[diff1][0];
	if(big[diff2][0] == same1 || big[diff2][0] == diff1 || big[diff2][0] == four || big[diff2][0] == -1){
		if(big[diff2][1] == same1 || big[diff2][1] == diff1 || big[diff2][1] == four || big[diff2][1] == -1){
			if(big[diff2][2] == same1 || big[diff2][2] == diff1 || big[diff2][2] == four || big[diff2][2] == -1){
				f = 0;
			}else now += a[big[diff2][2]];
		}else now += a[big[diff2][1]];
	}else now += a[big[diff2][0]];
	return now;
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ){
		cin >> a[i];
		for(int j = 0; j <= 2; j ++ ) big[i][j] = -1;
	}
	for(int i = 1; i <= m; i ++ ){
		int x, y; cin >> x >> y;
		q[x].pb({a[y], y});
		q[y].pb({a[x], x});
		edges.pb({x, y});
		if(x != y) ans = max(ans, a[x] + a[y]);
	}
	for(int i = 1; i <= n; i ++ ) ans = max(ans, a[i]);
	for(int i = 1; i <= n; i ++ ){
		sort(all(q[i]));
		int len = q[i].size();
		if(len >= 1) big[i][0] = q[i][len - 1].se;
		if(len >= 2) big[i][1] = q[i][len - 2].se;
		if(len >= 3) big[i][2] = q[i][len - 3].se;
	}
	for(int i = 0; i < m; i ++ ){
		for(int j = 0; j < m; j ++ ){
			if(i == j) continue;
			int x = edges[i].fi, y = edges[i].se, xx = edges[j].fi, yy = edges[j].se;
			if(x == xx) ans = max(ans, work(x, xx, y, yy));
			if(x == y) ans = max(ans, work(x, y, xx, yy));
			if(y == xx) ans = max(ans, work(y, xx, x, yy));
			if(y == yy) ans = max(ans, work(y, yy, x, xx));
		}
	}
	cout << ans << endl;
	return 0;
}

I. This is an easy problem

  • 思路:模拟
  • 代码
/*
* @Author: 	Hfuubigstrength
* @email:	2854614012@qq.com
* @Date:   2024-05-28 23:26:33
*/
#include <bits/stdc++.h>
//#define int long long
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define debug(a) cout<<#a<<"="<<a<<endl;
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()
using namespace std;

int n;

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n;
	int cnt = 0;
	while(n){
		cnt += n % 2;
		n /= 2;
	}
	cout << cnt;
	return 0;
}

J. Trade

  • 思路:dp, d p [ i ] [ j ] dp[i][j] dp[i][j]表示,走到第 i , j i, j i,j的路径上的 ∑ b [ i ] [ j ] \sum{b[i][j]} b[i][j],转移方式类似摘花生那题并要结合条件判断当前点是否是利润非负。最后看最后一行或者最后一列有没有小于无穷大的数即可。
  • 代码
/*
* @Author: 	Hfuubigstrength
* @email:	2854614012@qq.com
* @Date:   2024-05-29 00:46:32
*/
#include <bits/stdc++.h>
//#define int long long
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define debug(a) cout<<#a<<"="<<a<<endl;
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()
using namespace std;

const int N = 1010;
LL a[N][N], b[N][N], dp[N][N];
int n, m;

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ){
		for(int j = 1; j <= m; j ++ ){
			cin >> a[i][j];
			dp[i][j] = 9e18;
		}
	}
	for(int i = 1; i <= n; i ++ ){
		for(int j = 1; j <= m; j ++ ){
			cin >> b[i][j];
		}
	}
	dp[1][1] = b[1][1];
	for(int i = 1; i <= n; i ++ ){
		for(int j = 1; j <= n; j ++ ){
			if(i == 1 && j == 1) continue;
			if(i >= 2) dp[i][j] = min(dp[i - 1][j], dp[i][j]);
			if(j >= 2) dp[i][j] = min(dp[i][j - 1], dp[i][j]);
			dp[i][j] += b[i][j];
			if(a[i][j] - a[1][1] - dp[i][j] < 0) dp[i][j] = 9e18;
		}
	}
	bool f = 0;
	for(int i = 1; i <= n; i ++ ){
		if(dp[i][m] < 9e18) f = 1;
	}
	for(int i = 1; i <= m; i ++ ){
		if(dp[n][i] < 9e18) f = 1;
	}
	if(f) cout << "YES";
	else cout << "NO";
	return 0;
}

K. Puzzle

  • 思路:纯模拟
  • 代码:
#include <bits/stdc++.h>
//#define int long long
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define debug(a) cout<<#a<<"="<<a<<endl;
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()
using namespace std;

int a[10];
set<int>s;
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> a[1] >> a[2] >> a[3] >> a[4];
	sort(a + 1, a + 5);
	set<int>s;
	do{
		for(int i = 1; i <= 3; i ++ ){
		for(int j = 1; j <= 3; j ++ ){
			for(int k = 1; k <= 3; k ++ ){
				if(i == 1 && j == 1 && k == 1) s.insert(a[1] + a[2] +a[3] + a[4]);
				if(i == 1 && j == 1 && k == 2) s.insert(a[1] + a[2] +a[3] - a[4]);
				if(i == 1 && j == 1 && k == 3) s.insert(a[1] + a[2] +a[3] * a[4]);
				if(i == 1 && j == 2 && k == 1) s.insert(a[1] + a[2] -a[3] + a[4]);
				if(i == 1 && j == 2 && k == 2) s.insert(a[1] + a[2] -a[3] - a[4]);
				if(i == 1 && j == 2 && k == 3) s.insert(a[1] + a[2] -a[3] * a[4]);
				if(i == 1 && j == 3 && k == 1) s.insert(a[1] + a[2] *a[3] + a[4]);
				if(i == 1 && j == 3 && k == 2) s.insert(a[1] + a[2] *a[3] - a[4]);
				if(i == 1 && j == 3 && k == 3) s.insert(a[1] + a[2] *a[3] * a[4]);

				if(i == 2 && j == 1 && k == 1) s.insert(a[1] - a[2] +a[3] + a[4]);
				if(i == 2 && j == 1 && k == 2) s.insert(a[1] - a[2] +a[3] - a[4]);
				if(i == 2 && j == 1 && k == 3) s.insert(a[1] - a[2] +a[3] * a[4]);
				if(i == 2 && j == 2 && k == 1) s.insert(a[1] - a[2] -a[3] + a[4]);
				if(i == 2 && j == 2 && k == 2) s.insert(a[1] - a[2] -a[3] - a[4]);
				if(i == 2 && j == 2 && k == 3) s.insert(a[1] - a[2] -a[3] * a[4]);
				if(i == 2 && j == 3 && k == 1) s.insert(a[1] - a[2] *a[3] + a[4]);
				if(i == 2 && j == 3 && k == 2) s.insert(a[1] - a[2] *a[3] - a[4]);
				if(i == 2 && j == 3 && k == 3) s.insert(a[1] - a[2] *a[3] * a[4]);

				if(i == 3 && j == 1 && k == 1) s.insert(a[1] * a[2] +a[3] + a[4]);
				if(i == 3 && j == 1 && k == 2) s.insert(a[1] * a[2] +a[3] - a[4]);
				if(i == 3 && j == 1 && k == 3) s.insert(a[1] * a[2] +a[3] * a[4]);
				if(i == 3 && j == 2 && k == 1) s.insert(a[1] * a[2] -a[3] + a[4]);
				if(i == 3 && j == 2 && k == 2) s.insert(a[1] * a[2] -a[3] - a[4]);
				if(i == 3 && j == 2 && k == 3) s.insert(a[1] * a[2] -a[3] * a[4]);
				if(i == 3 && j == 3 && k == 1) s.insert(a[1] * a[2] *a[3] + a[4]);
				if(i == 3 && j == 3 && k == 2) s.insert(a[1] * a[2] *a[3] - a[4]);
				if(i == 3 && j == 3 && k == 3) s.insert(a[1] * a[2] *a[3] * a[4]);
			}
		}
	}
	}while(next_permutation(a + 1,a + 1 + 4));
	cout << sz(s);
	return 0;
}

### 关于2024 ICPC在线竞赛题目解答 对于希望获取2024年国际大学生程序设计竞赛(ICPC)网络赛题目的解答或解析,通常这类资源会在比赛结束后一段时间内由官方或其他社区成员发布。目前可利用多个平台来跟踪最新动态并参与讨论。 #### 官方渠道与社区支持 - **ICPC官方网站**:这是最权威的信息源,会公布正式的比赛结果以及可能发布的标准解法[^1]。 #### 社区贡献的解决方案 许多编程爱好者和参赛者会在赛后分享自己的思路和技术细节。可以关注以下几个活跃的技术交流网站: - **Codeforces博客板块**:这里经常有经验丰富的选手撰写详细的赛后分析文章[^3]。 - **TopCoder论坛**:尽管主要服务于自家赛事,但也涵盖了广泛的算法话题,包括对其他公开赛事的看法。 - **LeetCode Discuss**:除了日常刷题外,该区域也适合探讨各类竞赛中的难题。 #### 自学准备建议 为了更好地理解未来可能出现的标准答案,在等待期间可以通过研究过往相似类型的题目来进行预习。例如,通过访问A2 Online Judge、SPOJ等站点上的动态规划(DP)分类练习,有助于积累解决复杂问题的经验。 ```python # 示例:如何在Python中实现一个简单的动态规划求斐波那契数列函数 def fibonacci(n, memo={}): if n in memo: return memo[n] elif n <= 2: result = 1 else: result = fibonacci(n-1, memo) + fibonacci(n-2, memo) memo[n] = result return result ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值