2026-09-08 hetao1733837 的刷题记录

LGP8346 「Wdoi-6」最澄澈的空与海

原题链接:「Wdoi-6」最澄澈的空与海

分析

这个结论是好猜的吧......

就相当于是,我第一要求原图联通(不存在 deg 为 0 0 0 的点),第二,我要求存在两个 deg 为 2 2 2 的点,且这两个点之间有连边,也必须属于两部?

有没有漏什么性质?

这输入格式也太反人类了吧?


写了一些奇怪的状物,其实底层是判断一些可以多次配对的东西,不出意外地 WA 了。看一下题解。

我们看到了类似于 deg 的东西,那不妨借用 toposort 的思路,直接写就行了。


都有 d e g deg deg 和环了,你还想不到拓扑排序?

正解

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int T;
int n, m;
int deg[N << 1];
vector<int> e[N << 1];
bool vis[N << 1];
void init(){
	for (int i = 1; i <= 2 * n; i++) {
        e[i].clear();
        deg[i] = 0;
        vis[i] = false;
    }
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	for (int cs = 1; cs <= T; cs++){
		init();
		cin >> n >> m; 
		for (int i = 1, u, v; i <= m; i++){
			cin >> u >> v;
			e[u].push_back(v + n);
			e[v + n].push_back(u);
			deg[u]++;
			deg[v + n]++;
		}
		queue<int> q;
		for (int i = 1; i <= n * 2; i++){
			q.push(i);
		}
		int cnt = 0;
		while (!q.empty()){
			int u = q.front();
			q.pop();
			if (vis[u] || deg[u] != 1)
				continue;
			int tmp = -1;
			for (auto v : e[u]){
				if (!vis[v]){
					tmp = v;
					break;
				}
			}
			if (tmp == -1)
				continue;
			vis[u] = vis[tmp] = true;
			cnt += 2;
			for (auto v : e[tmp]){
				if (!vis[v]){
					deg[v]--;			
					if (deg[v] == 1){
						q.push(v);
					}
				}
			}
		}
		if (cnt == n * 2)
			cout << "Renko" << '\n';
		else
			cout << "Merry" << '\n';
	}
}

LGP12848 蓝桥杯 2025 国 A 游戏

原题链接:蓝桥杯 2025 国 A 游戏

分析

好像要求出来,就是我们似乎往 n n n 连边是优的?就是找 1 1 1 的数的个数?这个怎么证明正确啊Σ(っ °Д °;)っ


别急,我猜他和最长上升子序列有关系。别急,好像还真让我猜到了什么。不过不全......

被证实了一些东西......不过,我们好像直接写一个树状数组......然后......还有什么吗?我也不知道😭

bur,咋才能把这个东西想得更清楚呢?

我要看题解了😭

答案一定不超过 2 2 2!!!

哦,我们连一下 ( 1 , n ) (1,n) (1,n) 和 ( n − 2 , n ) (n-2,n) (n−2,n)!

哦,就是说,因为始终有 n n n 的位置可以保证为空,则我们直接做就行了。


这是个题?跳了我😭

正解

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 300005;
int n, a[N];
bool check0(){
    for (int i = 1; i < n; i++){
        if (a[i] != i)
            return false;
    }
    return true;
}
bool check1(){
    int L = 1, R = n - 1;
    while (L < n && a[L] == L)
        L++;
    while (R >= 1 && a[R] == R)
        R--;
    if (L > R)
        return true;
    int pos = 0;
    for (int i = L; i <= R; i++){
        if (a[i] == R){
            pos = i;
        }
    }
    for (int i = pos; i >= L; i--){
        if (a[i] != R - (pos - i))
            return false;
    }
    for (int i = pos + 1; i <= R; i++){
        if (a[i] != L + (i - pos - 1))
            return false;
    }
    return true;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i < n; i++){
        cin >> a[i];
    }
    if (check0()){
        cout << 0;
        return 0;
    }
    if (check1()){
        cout << 1;
        return 0;
    }
    else{
        cout << 2;
        return 0;
    }
}

AT_arc227_f ARC227F Erase and Raise

原题链接:F. Erase and Raise

LGP1381 单词背诵

原题链接:单词背诵

分析

难道说,我邪修一下,对于第一个答案,拿一个 map 写一下,第二个,我拿两个模数写一个前缀和状物......这真的对吗?

但是,精细实现可以通过 O ( m n ) O(mn) O(mn),对的......

但是,那是没有意义的啊......一般来说,我可能会写一个字典树吗?那不是......不对,字典树并不对。

所以,到底怎么做😭


那个 map 竟然随便做,我力竭了......

正解

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, m;
string s[N], t[N];
map<string, int> sum;
map<string, bool> buc;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++){
		cin >> s[i];
		buc[s[i]] = true;
	}
	cin >> m;
	int pos = 1;
	int cnt = 0;
	int ans = 0x3f3f3f3f;
	for (int i = 1; i <= m; i++){
		cin >> t[i];
		if (buc[t[i]]){
			sum[t[i]]++;
		}
		if (sum[t[i]] == 1){
			cnt++;
			ans = i - pos + 1;
		}
		while (pos <= i){
			if (!buc[t[pos]]){
				pos++;
				continue;
			}
			if (sum[t[pos]] >= 2){
				sum[t[pos]]--;
				pos++;
                continue;
			}
			break;
		}
		ans = min(ans, i - pos + 1);
	}
	cout << cnt << '\n';
	cout << ans;
}

LGP8347 「Wdoi-6」另一侧的月

原题链接:「Wdoi-6」另一侧的月

分析

别急,操作次数是否一定呢?


我又双叒叕读错题了😭

就是说,我每次操作,肯定要找到一个对于当前是有利的对吧。怎么说呢?就是说......

不是,我都看了两集战锤了,为啥还不会???

对于一条链......这个怎么做?

菊花和完全二叉树是好做的对吧......或者说我蒙对了......

一旦一个节点的度数为偶数,则先手必胜;反之,后手必胜。证明显然,和我们蒙出来的差不多。

正解

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int T;
int n;
int deg[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> T;
    for (int cs = 1; cs <= T; cs++){
        memset(deg, 0, sizeof(deg));
        cin >> n;
        for (int i = 1, u, v; i < n; i++){
            cin >> u >> v;
            deg[u]++;
            deg[v]++;
        }
        bool flag = false;
        for (int i = 1; i <= n; i++){
            if (deg[i] % 2 == 0){
                flag = true;
                break;
            }
        }
        if (flag)
            cout << "Hifuu" << '\n';
        else{
            cout << "Luna" << '\n';
        }
    }
}

所以说,博弈论系列题目,其实,你想到一个贪心之后,我们只需要再次进行推广即可得到正确的博弈判断。

LGP5043 【模板】树同构 / BJOI2015 树的同构

原题链接:【模板】树同构 / BJOI2015 树的同构

分析

努力理解一下......

正解

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 55;
const int rnd = mt19937_64(time(0))();
int gethash(int x){
	x ^= rnd;
	x ^= x << 13;
	x ^= x >> 7;
	x ^= x << 17;
	x ^= rnd;
	return x;
}
int m;
int n;
vector<int> e[N];
int w[N], rt[N];
map<int, int> tr;
void dfs(int u){
	w[u] = 1;
	for (auto v : e[u]){
		dfs(v);
		w[u] += gethash(w[v]);
	}
}
void getrt(int u){
	for (auto v : e[u]){
		rt[v] = w[v] + gethash(rt[u] - gethash(w[v]));
		getrt(v);
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> m;
	for (int cs = 1; cs <= m; cs++){
		for (int i = 1; i <= n; i++){
			e[i].clear();
		}
		int root = 0;
		cin >> n;
		for (int i = 1, fa; i <= n; i++){
			cin >> fa;
			if (fa == 0){
				root = i;
				continue;
			}
			e[fa].push_back(i);
		}
		dfs(root);
		rt[root] = w[root];
		getrt(root);
		int tmp = 1;
		for (int i = 1; i <= n; i++){
			tmp += gethash(rt[i]);
		}
		if (tr.find(tmp) == tr.end()){
			tr[tmp] = cs;
		}
		cout << tr[tmp] << '\n';
	}
}

LGP1510 精卫填海

原题链接:精卫填海

分析

第 999 999 999 道题......

直接

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 10005;
int v, n, c;
int k[N], m[N];
int dp[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> v >> n >> c;
    for (int i = 1; i <= n; i++){
        cin >> k[i] >> m[i];
    }
    for (int i = 1; i <= n; i++){
        for (int j = c; j >= m[i]; j--){
            dp[j] = max(dp[j], dp[j - m[i]] + k[i]);
        }
    }
    for (int j = 0; j <= c; j++){
        if (dp[j] >= v){
            cout << c - j;
            return 0;
        }
    }
    cout << "Impossible";
    return 0;
}

LGP17413 「IXOI R3」时间复杂度分析

原题链接:「IXOI R3」时间复杂度分析

分析

第 1000 1000 1000 道题,始于红题,终于红题......前路漫漫,加油!

正解

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 500000000;
int n;
signed main(){
    ios::sync_with_stdio(0);
    cout.tie(0);
    cin.tie(0);
    cin >> n;
    if (n > N){
        cout << "O(1)";
        return 0;
    }
    else if (n * n <= N){
        cout << "O(n^2)";
        return 0;
    }
    else if (n <= N){
        cout << "O(n)";
        return 0;
    }
    
    else{
        cout << "O(1)";
        return 0;
    }
}
相关推荐
码匠许师傅1 小时前
【设计模式精讲】25.状态模式(State)
c++·ui·设计模式·状态模式·uml
C++ 老炮儿的技术栈1 小时前
MFC CPtrArray的用法
开发语言·数据结构·c++·算法·mfc·c
佳児素花痴╮1 小时前
C++基础速通
开发语言·c++
weixin_446260851 小时前
CABAL:用于追踪同行评审中合谋投标影响的多智能体仿真框架
人工智能·算法·机器学习
不会就选b1 小时前
算法日常・每日刷题--<贪心>6
数据结构·算法·leetcode
青山木2 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法
Tisfy2 小时前
LeetCode 3870.统计范围内的逗号:模拟 或 一步计算
数学·算法·leetcode·题解·模拟·遍历
明月_清风2 小时前
字符串匹配四大经典算法:BF、RK、BM、KMP 到底有什么区别?
后端·算法
程序喵大人2 小时前
【C++入门】值类别与表达式 - 03 引用绑定:为什么有些参数能接住临时对象
开发语言·c++·引用绑定