2020 ICPC 济南站 打铁实录

2020.12.27 ICPC 济南站 回顾
开始直接冲A题,翻译完一波,然后看看其他题目的情况,发现两道签到题,M题和G题,马上转战M题,hx直接得出结论,提交一波,WA,共同讨论一下马上发现问题所在,AC
A题

#include<bits/stdc++.h>
using namespace std;
int main() {
	int n, k;
	cin >> n >> k;
	if(k >= n) cout << 2 << endl;
	else {
		int ans = n * 2 / k;
        if((n * 2) % k != 0) ans++;
		cout << ans << endl;
	}
	return 0;
}

然后接着去写G题,hx琢磨一会儿得出了恒定一种方法的结论:x ^ (x ^ y) ,令z = x ^ y, 这样只需要一次 x ^ y即可得到 y ,提交一次WA,返回仔细检查发现 z 是有可能大于等于 x 的,所以需要分情况,大于 x 的情况怎么处理呢,hx继续琢磨,得出恒定两种方法的结论 首先 x ^ [x]反 得到 x = 全1,然后再 x ^ [y]反 得到 y,所以结果是 两次操作, 第一次操作的 A = (同x二进制位数的全1 异或 x),第二次操作的 A = (同x二进制位数的全1 异或 y),想法已经出来,马上码代码,结果WA,后面陆陆续续提交了3,4次,于是 zyj 立马转战C、D题,hx 和 我 继续磕G题,在计算全1和反码上 xqm 使用了字符串写法,结果还是错误,然后陆续提交了3次,最终发现 hx 修改了一个强制转换的位置,AC,赛后我仔细分析,发现我们原先计算全1的代码:ll ans = (ll)(pow(2, cnt) - 1); cnt是 x 的二进制位数,发现当pow计算的最多可达10^18,pow返回double值,由于double精度有限,10进制有效位大概在15~16位,所以在计算过程中可能会出现精度损失,导致结果出错。AC时的代码:ll ans = ((ll)pow(2, cnt) - 1); 仔细反思了一下,这个代码其实也是可能出错的,可能刚好测试点通过pow时是没有出现精度损失的,下面放出赛后修改后的代码
G题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
	ll x, y;
	cin >> x >> y;
	ll ans = 1;
	while(ans <= x) {
		ans <<= 1;
	}
	ans--;
    cout << 2 << endl;
    cout << (ans ^ x) << " " << (ans ^ y) << endl; 
	return 0;
}

C题是在G题前面被 zyj 一次AC的,真好,大致思路是石头数量为3的石堆是不用管,不需要花钱,然后石头数量为1的堆和石头数量为2的堆互相结合,花的钱为堆数较少者的堆数*2,然后有剩余的堆再单独分情况,目前我思路还不清除,等我理清楚了再补。
C题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
	ll a, b, c;
	cin >> a >> b >> c;
	ll ans = 0;
	if (a > b) {
		ans = b * 2;
		int tmp = a - b;
		int xx = (tmp - 1) / 3, yy = (tmp - 1) % 3;
		if(yy == 0) ans += xx * 3;
		else if (yy == 1) ans += xx * 3 + 1;
		else if(yy == 2) ans += xx * 3 + 3;
	}
	else if (a == b) ans = b * 2;
	else {
		ans = a * 2;
		int tmp = b - a;
		int xx = (tmp - 1) / 3, yy = (tmp - 1) % 3;
		if(yy == 0) ans += xx * 6;
		else if (yy == 1) ans += xx * 6 + 4;
		else if (yy == 2) ans += xx * 6 + 6;
	}
	cout << ans << endl;
}

C题G题过了后转战D题,开始的时候是在纠结原计划是啥,zyj 肯定原计划是所有人都选择最大值Ri,后面仔细琢磨题意,确实是这样,没有疑问后我直接开做,大致思路是先按照R值升序排序,然后如果相同R值的点取它们中最大L值,且保证
这个值不能小于等于左边不是相同R值的点,这样能保证现在每个人的分数不会小于原先的分数,因为我将分数保证了和之前是一样的,而且能得到最小sum,结果一交,WA,后面 hx 也撸了个代码,结果也WA了,后面琢磨了半天,WA了好几次,然后读了好几次题目,发现其他每个人的分数其实是可以提高的,只要不小于即可,好了修改了一个小细节后,AC,还是得吸取教训,多读题。
D题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
struct node {
	int L, R, s;
} st[maxn];
bool cmp(node a, node b) {
	if(a.R != b.R) return a.R < b.R;
	return a.L > b.L;
}
int main() {
	int n; cin >> n;
	for(int i = 1; i <= n; i++) cin >> st[i].L >> st[i].R;
	sort(st+1, st+n+1, cmp);
	st[0].L = st[0].R = st[0].s = -1;
	for(int i = 1; i <= n; i++) {
		if(st[i].R != st[i-1].R) {
			if(st[i].L > st[i-1].s) st[i].s = st[i].L;
			else st[i].s = st[i-1].s;
		}
		else st[i].s = st[i-1].s;
	}
	ll sum = 0;
	for(int i = 1; i <= n; i++) sum += st[i].s;
	cout << sum << endl;
}

写完D题,发现已经排到了400多,气人,人均4题,按照我们队伍的目前这个情况,只有再做一题才有可能拿奖,哎,继续冲A题,这个点时间已经不多,磨了半天,发现没啥思路,只能发现结果大概是2的多少次方,然后我们就根据测试样例开始盲猜,特判,哎,没办法,是真滴cai。

其他题目这几天补一补,看能不能再做出几个。

第一次ICPC分站赛到此结束,打铁了还是挺可惜的,不过潜力还是蛮大的,差不多是第一次正式接触ICPC分站赛,大概训练了不到一个月吧,之前没怎么打过这种思维题目,不太习惯,发现前面几道题基本上都不涉及什么算法,纯思维,想到了就出来了,以后还是得多做这种题目吧,冲,明年ICPC见,希望明年能拿个铜,哎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值