NOIP2025专题-搜索&模拟(25直升搜索模拟)

卸载前main

本来在写DP专题的,但是刚刚写完的时候一脚把主机踹了,全没了!!!!!!!【超大声】啊啊啊啊啊啊啊啊我讨厌你们我真的想哭啊啊啊啊啊啊啊啊啊啊啊啊遂颓博客。
因为肝硬化泰蒻辣,遂好多都看了题解,所以这一堆仅供自己观看,不要把我的当正经教程,这对你的OI水平会有反作用的


开始题解!

T1 小木棍

棍啊一堆**!!!!!!我讨厌你!!!
题目链接


Solve

我不会搜索我太菜了
于是我看了题解。【大言不惭】
然后我好像会了。
复述一遍。
思路:
1.首先我们可以在dfs外面枚举出要拼接的棍子长度,取值范围肯定就是 \([输入的最长的一根棍子,所有棍子长度的总和]\),然后每次找一个能被长度总和整除的数来dfs(肯定不能拼半根棍子就跑啊题干不让),然后这里可以只枚举到 \(\frac{所有棍子长度的总和}{2}\),如果没有找到答案那么就直接输出所有棍子长度的总和,相当于一个小优化。
2.可以设 \(dfs(int~~tot,~~int~~num,~~int~~l)\) 分别表示已经拼成了 \(tot\) 根符合长度的棍子,上一次用的的是编号为 \(num\) 的棍子,当前这一根大棍子还剩下 \(l\) 的长度没拼好,然后就可以枚举剩下的棍子了。
-可是会TLE,怎么办?
-做一些逆天优化/剪枝罢。
1.对输入的棍子从大到小排序。(因为这一篇是给我自己看的我能看懂所以我不多解释为什么了,别人看到了也不要去问我,最好直接爬我放的题目链接的第一篇题解就好了,那个比我说的清楚多了。【真的!!!!!!!】)
2.每次拼接时,如果上次用到第 \(i\) 根,那么下一次就从第 \(i + 1\) 根开始往后搜。
3.dfs搜失败了的时候,回溯回来时就不要再使用跟刚刚使用过的一样长的棍子了,可以用一个 \(nxt\) 数组存下第一个比当前短的棍子的位置
4.可以用二分找小于等于 \(l\) 的第一根木棍位置,然后往后搜(因为序列是有序的)。
5.开一个 \(v\) 数组表示当前的棍子是否被用过,回溯时删除标记
6.因为是从小到大枚举的长度,所以第一次找到的答案就是最优的,直接跳出dfs,输出答案即可返回程序。
7.(这个我没想到【大悲】,这里霍亿下题解喵~)如果当前长棍剩余的未拼长度等于当前木棍的长度或原始长度,继续拼下去时却失败了,就直接回溯并改之前拼的木棍。
原因:
当前长棍剩余的未拼长度等于当前木棍的长度时,这根木棍在最优情况下显然是拼到这(如果用更多短木根拼完剩下的这段,把这根木棍留到后面显然不如把更多总长相等的短木棍扔到后面)。如果在最优情况下继续拼下去失败了,那肯定是之前的木棍用错了,回溯改即可。
当前长棍剩余的未拼长度等于原始长度时,说明这根原来的长棍还一点没拼,现在正在放入一根木棍。很明显,这根木棍还没有跟其它棍子拼接,如果现在拼下去能成功话,它肯定是能用上的,即自组或与其它还没用的木棍拼接。但继续拼下去却失败,说明现在这根木棍不能用上,无法完成拼接,所以回溯改之前的木棍。
ps:肝硬化希望自己能把这些优化剪枝全学会这可能会对它几乎没有的OI水平有正作用………


Code

#include<bits/stdc++.h>
using namespace std;
int n, a[77], sum, nxt[77], genshu, len;
bool f, v[77];
bool hhh(int x, int y){
	return x > y;
}
void dfs(int tot, int num, int sh){//拼了几根,编号,这一根剩余长度
	int i;
	if(! sh){
		if(tot == genshu){
			f = 1;
			return ; 
		}
		for(i = 1; i <= n; i ++){
			if(! v[i]){
				break;
			}
		}
		v[i] = 1;
		dfs(tot + 1, i, len - a[i]);
		v[i] = 0;
		if(f){
			return ;
		}
	}
	int l = num + 1, r = n;
	while(l < r){
		int mid = (l + r) >> 1;
		if(a[mid] <= sh){
			r = mid;
		}
		else{ 
			l = mid + 1;
		}
	}
	for(i = l; i <= n; i ++){
		if(! v[i]){
			v[i] = 1;
			dfs(tot, i, sh - a[i]);
			v[i] = 0;
			if(f){
				return ;
			}
			if(sh == a[i] || sh == len){
				return ;
			}
			i = nxt[i];
			if(i == n){
				return ;
			}
		} 
	}
	return ;
}
int main(){
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		sum += a[i];
	}
	sort(a + 1, a + n + 1, hhh);
	nxt[n] = n;
	for(int i = n - 1; i; i --){
		if(a[i] == a[i + 1]){
			nxt[i] = nxt[i + 1];
		}
		else{
			nxt[i] = i;
		}
	}
	for(len = a[1]; len <= sum / 2; len ++){
		if(sum % len){
			continue;
		}
		else{
			genshu = sum / len;
			f = 0;
			v[1] = 1;
			dfs(1, 1, len - a[1]);
			v[1] = 0;
			if(f){
				cout << len;
				return 0;
			}
		}
	}
	cout << sum;
	return 0;
}

T2 [NOIP2015 提高组] 斗地主 加强版

我是老农民
题目链接
吐槽:谁家好人这么出牌啊。。。他像那种打牌打不赢于是自己改规则的那种。。。


Solve

思路:感觉像个大魔拟欸,于是肝硬化开始思考………(其实有更好的DP做法但是肝硬化泰蒻不会DP于是抛弃大脑写暴搜)
首先不能瞎搜,反正牛牛自己跟自己玩,出牌顺序他爱咋出咋出不要紧,于是我们钦定每次出牌一定要把手里最小的牌出出去。那么我们可以进行分讨
1.顺子: \(三顺子>双顺子>正经顺子\) (此处及之后的“ \(>\) ”均为模拟的优先级);
2.出一张最小的带其它: \(二单带四>一带三\)
3.出两张最小的带其它: \(二对带四>一对带四>一对带三\)
4.出三张最小的带其它: \(三带一对>三带一\)
5.出四张最小的带其它: \(四带二对>四带二单\)
6.只出最小的: \(炸弹>三张>对>单张\)
7. 王炸。
于是可以愉快地大模拟啦!


Code

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int _ = 110;
int t, n, x, y, a[_], ans;
inline void dfs(int da){
	if(da >= ans){
		return ;
	}
	int h = 0;
	for(int i = 2; i <= 16; i ++){
		if(a[i]){
			h = i;
			break;
		}
	}
	if(! h){
		ans = min(ans, da);
		return ;
	}
	//cout<<'a';
	if(h >= 3 && h <= 13){//三个一组至少六张的逆天顺子。
		int len = 0;
		for(int i = 1; h + i - 1 <= 14; i ++){
			if(a[h + i - 1] < 3){
				break;
			}
			len = i;
		}
		if(len < 2){
			goto ershun;
		}
		for(int j = h; j <= h + len - 1; j ++){
			a[j] -= 3;
		}
		for(int j = h + len - 1; j >= h; j --){
			if(j - h + 1 < 2){
				a[j] += 3;
				continue;
			}
			dfs(da + 1);
			a[j] += 3;
		}
	}
	ershun:
	if(h >= 3 && h <= 12){//两个一组至少六张的逆天顺子。
		int len = 0;
		for(int i = 1; h + i - 1 <= 14; i ++){
			if(a[h + i - 1] < 2){
				break;
			}
			len = i;
		}
		if(len < 3){
			goto yishun;
		}
		for(int j = h; j <= h + len - 1; j ++){
			a[j] -= 2;
		}
		for(int j = h + len - 1; j >= h; j --){
			if(j - h + 1 < 3){
				a[j] += 2;
				continue;
			}
			dfs(da + 1);
			a[j] += 2;
		}
	}
	yishun:
	if(h >= 3 && h <= 10){//正经顺子。
		int len = 0;
		for(int i = 1; h + i - 1 <= 14; i ++){
			if(a[h + i - 1] < 1){
				break;
			}
			len = i;
		}
		if(len < 5){
			goto ndaidan;
		}
		for(int j = h; j <= h + len - 1; j ++){
			a[j] -= 1;
		}
		for(int j = h + len - 1; j >= h; j --){
			if(j - h + 1 < 5){
				a[j] += 1;
				continue;
			}
			dfs(da + 1);
			a[j] += 1;
		}
	}
	ndaidan:
	if(a[h] >= 1){
		a[h] --;
		for(int i = 2; i <= 16; i ++){//二单带四。 
			if(a[i] >= 4){
				a[i] -= 4;
				for(int j = 2; j <= 16; j ++){
					if(i != h && j != h){
						if(a[j] >= 1){
							a[j] --;
							dfs(da + 1);
							a[j] ++;
						}
					}
				}
				a[i] += 4;
			}
		}
		for(int i = 2; i <= 16; i ++){//一带三。
			if(h != i){
				if(a[i] >= 3){
					a[i] -= 3;
					dfs(da + 1);
					a[i] += 3;
				}
			}
		}
		a[h] ++;
	}
	//ndaidui
	if(a[h] >= 2){
		a[h] -= 2;
		for(int i = 2; i <= 16; i ++){//二对带四。
			if(a[i] >= 4){
				a[i] -= 4;
				for(int j  = 2; j <= 16; j ++){
					if(i != h && j != h){
						if(a[j] >= 2){
							a[j] -= 2;
							dfs(da + 1);
							a[j] += 2;
						}
					}
				}
				a[i] +=  4;
			}
		}
		for(int i = 2; i <= 16; i ++){//一对带四。
			if(a[i] >= 4 && i != h){
				a[i] -= 4;
				dfs(da + 1);
				a[i] += 4;
			}
		}
		for(int i = 2; i <= 16; i ++){//一对带三。
			if(i != h && a[i] >= 3){
				a[i] -= 3;
				dfs(da + 1);
				a[i] += 3;
			}
		}
		a[h] += 2;
	}
	if(a[h] >= 3){
		a[h] -= 3;
		for(int i = 2; i <= 16; i ++){//三带一对。
			if(i != h && a[i] >= 2){
				a[i] -= 2;
				dfs(da + 1);
				a[i] += 2;
			}
		}
		for(int i = 2; i <= 16; i ++){//三带一。
			if(i != h && a[i] >= 1){
				a[i] --;
				dfs(da + 1);
				a[i] ++;
			}
		}
		a[h] += 3;
	}
	if(a[h] >= 4){
		a[h] -= 4;
		for(int i = 2; i <= 16; i ++){//四带二对。
			if(a[i] >= 2){
				a[i] -= 2;
				for(int j = 2; j <= 16; j ++){
					if(i != h && j != h){
						if(a[j] >= 2){
							a[j] -= 2;
							dfs(da + 1);
							a[j] += 2;
						}
					}
				}
				a[i] += 2;
			}
		}
		for(int i = 2; i <= 16; i ++){//四带二单。
			if(a[i] >= 1){
				a[i] --;
				for(int j = 2; j <= 16; j ++){
					if(i != h && j != h){
						if(a[j] >= 1){
							a[j] --;
							dfs(da + 1);
							a[j] ++;
						}
					}
				}
				a[i] ++;
			}
		}
		a[h] += 4;
	}
	if(a[h] >= 4){//炸弹。
		a[h] -= 4;
		dfs(da + 1);
		a[h] += 4;
	}
	if(a[h] >= 3){//三张。
		a[h] -= 3;
		dfs(da + 1);
		a[h] += 3;
	}
	if(a[h] >= 2){//对。
		a[h] -= 2;
		dfs(da + 1);
		a[h] += 2;
	}
	if(a[h] >= 1){//散牌。
		a[h] --;
		dfs(da + 1);
		a[h] ++;
	}
	if(h == 15){//王炸。
		if(a[15] && a[16]){
			a[15] --;
			a[16] --;
			dfs(da + 1);
			a[15] ++;
			a[16] ++;
		}
	}
	return ;
}
int main(){
	scanf("%d%d", & t, & n);
	while(t --){
		ans = 999999999;
		memset(a, 0, sizeof(a));
		for(int i = 1; i <= n; i ++){
			scanf("%d%d", & x, & y);
			if(x){
				if(x == 1){//预处理:因为A比K大。
					a[14] ++;
				}
				else{
					a[x] ++;
				}
			}
			else{
				a[14 + y] ++;
			}
		}
		dfs(0);
		printf("%d\n", ans);
	}
	return 0;
}

T3 Expression

数学界来了个甜菜。
题目链接


Solve

考虑dfs,设 \(dfs(long~~long~~a,~~long~~long~~b,~~long~~long~~c,~~long~~long~~aa,~~long~~long~~ab,~~long long ac, long~~long~~jin,~~int~~len,~~int~~wei)\) (什么逆天法棍)\(a\)为当前还没处理,不知真假的形如 \(a+b=c\) 的式子中的 \(a\)\(b\)\(c\) 同理, \(aa,ab,ac\) 为当前的答案, \(jin\) 存的是进位的数, \(len\) 为当前拼出的式子的长度, \(len>=ans\) 时直接退出, \(wei\) 为每个数从低位到高位搜到了第几位。
1.当 \(c=0\) 时,只需要把 \(c\) 的最高位处理成 \(a+b+jin\) 就可以了。
2.当 \(a,b,c\) 的个位相等时,处理下一位时位数要加一。
3.对于其他情况,\(a,b,c\) 中两项不变,枚举变的那一项,注意这时需要让 \(len\)\(ans\) 比较进行剪枝。
4.当 \(a=b=c=jin=0\) 时就可以记录答案了。
ps:可以预处理出 \(10^{0}\) ~ \(10^{18}\)


Code

#include <bits/stdc++.h>
using namespace std;
const int _ = 22;
long long x, y, z, asa, asb, asc, p[_], ans = 66;

inline void dfs(long long a, long long b, long long c, long long aa, long long ab, long long ac, long long jin, int len, int wei){
	if(len >= ans){
		return ;
	}
	if(! a && ! b && ! c && ! jin){//找到答案。
		ans = len, asa = aa, asb = ab, asc = ac;
		return ;
	}
	if(! c){//把c补上欠的数。
		long long as = a + b + jin;
		int h = 0;
		while(as){
			as /= 10;
			h ++;
		}
		dfs(0     , 0     , 0     , aa +  a       * p[wei], ab +  b       * p[wei], ac + (a + b + jin) * p[wei],                            0, len + h, wei + 1);
		return ;
	}
	if((a + b + jin) % 10 == c % 10){//最低位相等,处理下一位。
		dfs(a / 10, b / 10, c / 10, aa + (a % 10) * p[wei], ab + (b % 10) * p[wei], ac + (c % 10     ) * p[wei], (a % 10 + b % 10 + jin) / 10, len    , wei + 1);
	}
	dfs(a * 10 + (c % 10 - (b % 10 + jin) + 10) % 10, b                                           , c                                         , aa, ab, ac, jin, len + 1, wei);//加a。
	dfs(a                                           , b * 10 + (c % 10 - (a % 10 + jin) + 10) % 10, c                                         , aa, ab, ac, jin, len + 1, wei);//加b。
	dfs(a                                           , b                                           , c * 10 + (a % 10 + b % 10 + jin) % 10     , aa, ab, ac, jin, len + 1, wei);//加c。
	return ;
}
int main(){
	p[1] = 10;
	p[0] = 1;
	for(int i = 2; i <= 18; i ++){
		p[i] = p[i - 1] * p[1];
	}
	scanf("%lld+%lld=%lld", & x, & y, & z);
	dfs(x, y, z, 0, 0, 0, 0, 0, 0);
	printf("%lld+%lld=%lld", asa, asb, asc);
	return 0;
}

update at:25.8.23.8:20

喜报:肝硬化被 \(Hack\) 了!!!!111

-我被 \(Hack\) 了!
-欸,为什么呀?
-让我们看这一组数据↓

2+4324=53245

-好嘛,又一数学界天才诞生。
-看看我们的输出↓

10002+43243=53245

-您这更天才,地球人都知道这才是其中一种最优答案↓

2+453243=453245

-你说得对,但是我们的程序会判断我给的式子只添了两个数,您的有三个。
-?逆天 \(ans\) ,五等于二,这让我想到一个脑筋急转弯:Q:二等于五,三等于十,四等于十五,那么五等于几?A:五等于二。但是这是为什么呢?
-因为我们没有判断添上一个高位上的数时,那一位是否挨着当前的高位,如果不是那就肯定有多余的零需要记录到 \(len\) 中,我们可以再调两个参: \(ka\)\(kb\) 分别来记录将来可能会加入到 \(len\) 中的, \(a\)\(b\) 里的零,具体操作就来看代码吧!


Code

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int _ = 22;
long long x, y, z, asa, asb, asc, p[_], ans = 66;

inline void dfs(long long a, long long b, long long c, long long aa, long long ab, long long ac, long long jin, int len, int wei, int ka, int kb){
	if(len >= ans){
		return ;
	}
	if(! a && ! b && ! c && ! jin){
		ans = len, asa = aa, asb = ab, asc = ac;
		return ;
	}
	if(! c){
		long long as = a + b + jin;
		int h = 0;
		while(as){
			as /= 10;
			h ++;
		}
		dfs(0     , 0     , 0     , aa +  a       * p[wei], ab +  b       * p[wei], ac + (a + b + jin) * p[wei],                            0, len + h, wei + 1, ka, kb);
		return ;
	}
	if((a + b + jin) % 10 == c % 10){
		if(! a){
			ka ++;
		}
		if(! b){
			kb ++;
		}
		dfs(a / 10, b / 10, c / 10, aa + (a % 10) * p[wei], ab + (b % 10) * p[wei], ac + (c % 10     ) * p[wei], (a % 10 + b % 10 + jin) / 10, len    , wei + 1, ka, kb);
	}
	dfs(a * 10 + (c % 10 - (b % 10 + jin) + 10) % 10, b                                           , c                                         , aa, ab, ac, jin, len + 1 + ka, wei, 0 , kb);
	dfs(a                                           , b * 10 + (c % 10 - (a % 10 + jin) + 10) % 10, c                                         , aa, ab, ac, jin, len + 1 + kb, wei, ka, 0 );
	dfs(a                                           , b                                           , c * 10 + (a % 10 + b % 10 + jin) % 10     , aa, ab, ac, jin, len + 1     , wei, ka, kb);
	return ;
}
int main(){
	p[1] = 10;
	p[0] = 1;
	for(int i = 2; i <= 18; i ++){
		p[i] = p[i - 1] * p[1];
	}
	scanf("%lld+%lld=%lld", & x, & y, & z);
	dfs(x, y, z, 0, 0, 0, 0, 0, 0, 0, 0);
	printf("%lld+%lld=%lld", asa, asb, asc);
	return 0;
}

T4 Anya and Cubes

此题曾写过,在此致歉喵。

题目链接


Solve

首先看题,发现这数据范围又没给模数,怎么存阶乘呢?再定睛一看发现 \(S\) 只到 \(1e16\) ,于是使用计算器发现到 \(19!\) 足矣大于 \(S\) ,就可以预处理出阶乘, \(dfs\) 时在加个判断。于是考虑暴搜,发现有三种状态:选原数、不选、选阶乘;直接暴搜是 \(O(3^n)\) ,无法接受。那么我们考虑优化——折半搜索\(Meet~~in~~the~~Middle\) ),于是搜索的复杂度可以降到 \(O(2·3^\frac{n}{2})\) ,可以通过;每次寻找答案可以开一个 \(map\) ,每次查询时间大约是 \(O(logn)\) 。不特意卡的话是可以过的,但是此题甚坏也,卡 \(map\) ,遂直接用 \(unordered\)_\(map\) 可以将查询优化到常数时间(因为它俩一个基于红黑树另一个基于哈希表\(hash~~table\) )),于是就可以通过此题了。


Code

#include <bits/stdc++.h>
using namespace std;
unordered_map<long long, long long> mp[30];
long long n, k, ans, s, a[30], jc[30];
void dfsa(int num, int usd, long long sum){
	if(sum > s || usd > k){
		return ;
	}
	if(num > (n >> 1)){
		mp[usd][sum] ++;
		return ;
	}
	dfsa(num + 1, usd, sum         );
	if(sum + a[num] <= s){
		dfsa(num + 1, usd, sum + a[num]);
	}
	if(a[num] <= 19 && usd < k && sum + jc[a[num]] <= s){
		dfsa(num + 1, usd + 1, sum + jc[a[num]]);
	}
	return;
}
void dfsb(int num, int usd, long long sum){
	if(sum > s || usd > k){
		return ;
	}
	if(num > n){
		for(int i = 0; i + usd <= k; i ++){
			if(mp[i]. count(s - sum)){
				ans += mp[i][s - sum];
			}
		}
		return;
	}
	dfsb(num + 1, usd, sum         );
	if(sum + a[num] <= s){
		dfsb(num + 1, usd, sum + a[num]);
	}
	if(a[num] <= 19 && usd < k && sum + jc[a[num]] <= s){
		dfsb(num + 1, usd + 1, sum + jc[a[num]]);
	}
	return;
}
int main() {
	cin >> n >> k >> s;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
	}
	jc[0] = 1;
	for(int i = 1; i <= 19; i ++){//已经超过1e17了喵,真的算了一下哦喵。
		jc[i] = jc[i - 1] * i;
	}
	dfsa(1, 0, 0);
	dfsb((n >> 1) + 1, 0, 0);
	cout << ans;
	return 0;
}

T5 Distinct Paths

数据范围,我好不容易看你一次,你却让我输得,这么彻底!哈哈哈…焯!
题目链接


Solve

首先看题,发现 \(1≤n,m≤1000\)八月新番《误闯天家:数据之大不可搜》,又看 \(1≤k≤10\) ,“每条路径经过的格子的颜色均不同”,而根据题目限制,路径长一定是 \(n+m-1\) ,那么如果 \(n+m-1>k\) 就是无解的,皇上,你数据范围是诈骗,是诈骗!!!
于是我们考虑暴搜+剪枝:
1.当剩余的步数大于剩余的颜色,那么一定无解,直接 \(return\) ;一种本质是相同的,也就是说对答案的贡献相同,计算一次,后面的直接累加即可;
3.由于数据范围只有 \(10\) ,可以考虑状压来记录使用过了哪种颜色。
于是我们就做完了!(ps:要注意取模!!!!!!!肝硬化为此半小时白干


Code

#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int cun[1111], n, m, k, a[22][22], dp[22][22], v[22];
inline int dfs(int x, int y){//x行y列。
	if(y > m){
		x ++;
		y = 1;
	}
	if(x > n){
		return 1;
	}
	int s = dp[x - 1][y] | dp[x][y - 1], c = k - cun[s], as = 0, h = - 1;
	if(c < n + m - x - y + 1){//路太长颜色不够用打死都拼不成及时止损。
		return 0;
	}
	for(int i = 1; i <= k; i ++){
		if(((a[x][y] && a[x][y] == i) || ! a[x][y]) && ((s >> (i - 1)) & 1) ^ 1){//这个点的颜色刚好就是要选的颜色或者这个点没颜色可以变成要选的颜色,并且它的必经之路曾经没这个颜色才能转移。
			dp[x][y] = s | (1 << (i - 1));
			v[i] ++;
			if(v[i] == 1){
				if(h == - 1){
					h = dfs(x, y + 1);
				}
				as = (as + h) % mod;//你在这个位置选每个整张图第一次选的颜色对答案的贡献都是一样的所以电风扇一次即可后面的累加答案就行。
			}
			else{
				as = (as + dfs(x, y + 1)) % mod;//颜色在整张图不是唯一出现那么就不能累加了老老实实电风扇。
			}
			v[i] --;//搜索回溯。
		}
	}
	return as;
}
int main(){
	for(int i = 1; i <= (1 << 10); i ++){//预处理存每种状态用过的颜色总数。
		cun[i] = cun[i >> 1] + (i & 1);
	}
	scanf("%d%d%d", & n, & m, & k);
	if(n + m - 1 > k){//路比颜色长打死拼不成数据范围是诈骗。
		printf("0");
		return 0;
	}
	for(int i = 1; i <= n; i ++){
		for(int j = 1; j <= m; j ++){
			scanf("%d", & a[i][j]);
			v[a[i][j]] ++;//统计各个颜色出现次数。
		}
	}
	printf("%d", dfs(1, 1));
	return 0;
}

6 [abc336_f]Rotation Puzzle

哈哈,这题干小嘴巴拉巴拉地说什么呢,想一头创似。
题目链接

posted @ 2025-08-18 22:11  养鸡大户肝硬化  阅读(34)  评论(5)    收藏  举报