水题狂欢赛 (爬楼梯赛)题解(偏向自我反省)

前言

这真的是一套水题。(就初一秒切那种(xsc0laoer是巨佬,不算)),但是zyq依旧非常f**k的去爬楼梯了。。。。

犯了各种奇奇怪怪的错误,题目看错,变量看错,改一点就可以让时间复杂度降次的优化发现不了,看到这套题水就想很快的A掉,完全不动脑筋,整个人都是浮躁的。

题易要犯错,题难不愿做,整个人特别浮躁,这一两周状态都特别差(喵喵喵 zyq状态好过吗)。心态都有点崩了。

考水题zyq还是爬楼梯去了,考CSP-2019 zyq 做到一半就去看《钢铁是怎样炼成的》去了。

没有办法沉下心来去想题,想半夜起床改代码结果一觉睡到天亮。。

笔者真的不是想在这里抱怨,真的不是想在在blog里散发负能量,只是想借着写这套水题题解的机会,说出自己长久以来的问题

尽管大家都A掉了这套题。很明显,这篇题解也不会有人认真去看,但是笔者还是想写一写这套让笔者爬楼梯的题的题解,以检查自己的思路是在什么地方卡住了。

废话就说到这儿了,勿以题难而不为 更勿以题易而不屑为。,与君共勉之。

T1 czq的集合差集

题目

题目

思路

\(A \cap B \ a \cup B\)等价于a ^ b

代码

#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;

unsigned long long a, b;
int main() {
	scanf("%llu %llu", &a, &b);
	printf("%llu", a ^ b);
	return 0;
}

T2 czq的原木种植

题目

题目

思路

设:有两根木头\(a\), \(b\)

不妨设\(len_a > len_b\)
需要砍\(k\)长度的木条 \((k > lenb)\)

\(a\)上砍后价值为 \((lena - k)^2 + lenb^2 = lena^2 + lenb^2 + lenc^2 - 2 \times k \times lena\)

\(b\)后为 \((lenb - k) ^ 2 + lena ^ 2 = lena^2 + lenb^2 + lenc^2 - 2 \times k \times lenb\)

又$\because lena > lenb $

\(\therefore (lena - k)^2 + lenb^2 < (lenb - k) ^ 2 + lena ^ 2\)

所以尽量找短的树砍,证毕

代码

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;

int n, k;
int a[maxn];
long long ans;
signed main() {
	scanf("%lld %lld", &n, &k);
	for(int i = 1; i <= n; i ++){
		scanf("%d", &a[i]);
	}
	sort(a + 1, a + n + 1);
	for(int i = 1; i <= n; i ++){
		if(k > a[i]){
			k -= a[i];
			a[i] = 0;
		}
		else{
			a[i] -= k;
			k = 0;
		}
		ans += (a[i] * a[i]);
	}
	printf("%lld", ans);
	return 0;
} 

T3 czq的陌上花开

题目

题目

思路

普普通通简单DP
\(dp[i] = min(dp[i - 1] + dp[i - 2]) + a[i]\)(dp[i]为经过i的最小值)

代码

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;

int a[maxn];
int n;
int dp[maxn];
signed main() {
	scanf("%lld", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%lld", &a[i]);
	}
	dp[1] = a[1];
	dp[2] = a[1] + a[2];
	for(int i = 3; i <= n; i ++){
		dp[i] = max(dp[i - 1], dp[i - 2]) + a[i];
	}
	printf("%lld", dp[n]);
	return 0;
}

T4 czq的骡马区间

题目

题目

思路

用一个map去存最后的那个那个点

吐槽

我谔谔,就是这道题我把题目理解错了,还能过样例就很神奇

代码

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;

int a[maxn];
int sum[maxn];
map<int, int> mp;
int n;
int tail[maxn];
int ans;
signed main() {
	scanf("%lld", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%lld", &a[i]);
		sum[i] = sum[i - 1] + a[i];
	}
	for(int i = n; i >= 1; i --){
		tail[i] = mp[a[i]];
		mp[a[i]] = i;
		if(tail[i]){
			ans += (sum[tail[i]] - sum[i - 1]);
		}
	}
	printf("%lld", ans);
	return 0;
}

T5 czq的原木种植

题目

题目

思路

并查集板题

只是将自己的值用一个循环赋到父节点上,就可以用\(O(n)\) A

代码

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int maxn = 2e5 + 5;
int n, m;
int a[maxn];
int fa[maxn];

int father(int x){
	if(fa[x] == x)return x;
	return fa[x] = father(fa[x]);
}

void join(int x, int y){
	int fax, fay;
	fax = father(x);
	fay = father(y);
	if(fax != fay){
		fa[fax] = fay;
	}
}

int maxans = 0;
int minans = 0x3f3f3f3f;
bool vis[maxn];
int sum[maxn];
signed main() {
	scanf("%lld %lld", &n, &m);
	for(int i = 1; i <= n; i ++){
		scanf("%lld", &a[i]);
		fa[i] = i;
	}
	for(int i = 1; i <= m; i ++){
		int x, y;
		scanf("%lld %lld", &x, &y);
		join(x, y);
	}
	for(int i = 1; i <= n; i ++){
		if(father(i) != i)a[father(i)] += a[i];
	}
	for(int i = 1; i <= n; i ++){
		int flag = father(i);
		int tot = 0;
		if(!vis[flag]){
			tot = a[flag];
			minans = min(minans, tot);
			maxans = max(maxans, tot);
		}
		vis[flag] = 1;
	}
	printf("%lld %lld", maxans, minans);
}

结语

zyq一边爬楼梯,一边反省自己,

写了一篇反省的blog,结果连下周班刊征稿的文章都有了。。。。

posted @ 2021-03-12 21:42  cqbzzyq  阅读(32)  评论(0编辑  收藏  举报