The Forbidden Permutation

本文介绍了如何使用C++解决禁止排列的问题。首先检查是否存在满足条件的好串,如果不满足则遍历所有情况寻找最小不满足条件。关键在于判断pos[a[i]]与pos[a[i+1]]的关系,并确定d的取值范围,确保满足题目的约束条件。做题时要注意仔细阅读样例,避免误解题目要求。
#include <bits/stdc++.h>
#define int long long
using namespace std;

int n, m, d;

void solve()
{
	cin >> n >> m >> d;
	vector<int> p(n + 1);
	vector<int> pos(n + 1);
	for (int i = 1; i <= n; i ++)
	{
		cin >> p[i]; // 排列
		pos[p[i]] = i;
	}
	vector<int> a(m + 1);
	int mmin = n + 1;
	int mmax = - n - 1;
	for (int i = 1; i <= m; i ++) cin >> a[i]; // 数组
	for (int i = 1; i < m; i ++)
	{
		if (pos[a[i]] >= pos[a[i + 1]] || pos[a[i + 1]] > pos[a[i]] + d)
		{
			cout << 0 << "\n";
			return ;
		}
		mmin = min(pos[a[i + 1]] - pos[a[i]], mmin);
		mmax = max(pos[a[i + 1]] - pos[a[i]], mmax); // 距离小于d
	}
	if (d + 1 - mmax <= mmin && d <= n - 2) cout << d - mmax + 1<< "\n"; // d + 1 大, mmax 小,所以d + 1 - mmax, 注意边界条件
	else cout << mmin << "\n";
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int t;
	cin >> t;
	while (t --)
	{
		solve();
	}
	return 0;
}

 先上代码。

思路:首先遍历一遍,如果有一个不满足,则是好串,直接退出,输出0

不是的话,遍历所有的情况,寻找到不满足的最小情况 ,分别是 pos[a[i]] >= pos[a[i + 1]]  和 pos[a[i]] > pos[a[i]] + d 这两种,情况。对于第二种情况,可以找到 d 的取值范围, a[i] , a[i + 1] 的距离是确定的 那 pos[a[i]] - pos[a[i + 1]] == d + 1 就是满足的最小情况,然后 pos[a[i]] 和 pos[a[i + 1]] 的最远距离是 n - 1 所以 d <= n - 2 必须满足。代码就是像上面那样。

我做这个题的时候看样例没有看全, 一直以为是 pos[a[i]] 的值 就是 p[a[i]] 的值导致怎么也理解不了,以后做题要仔细了,发现一直不懂的就多看几遍题。

链接:https://ac.nowcoder.com/acm/contest/108299/L 来源:牛客网 题目描述 It's a loving community! There are 𝑛 n residents in the community, and each resident 𝑖 ( 1 ≤ 𝑖 ≤ 𝑛 ) i (1≤i≤n) in the community has a unique resident 𝑎 𝑖 ( 1 ≤ 𝑖 ≤ 𝑛 ) a i ​ (1≤i≤n) in the community whom he/she loves so much. Each two residents love different residents. A resident can love himself / herself. It is guaranteed that 𝑛 n is even. One day, a bad thing happens: They need to choose 2 2 residents to be forbidden to get married forever. And to prevent such a thing from happening in the future, the rest 𝑛 − 2 n−2 residents decide to get married as 𝑛 2 − 1 2 n ​ −1 couples, each couple consisting of 2 2 persons (of course). It makes no sense that a couple consists of resident 𝑥 x and resident 𝑦 y while neither 𝑥 x loves 𝑦 y nor 𝑦 y loves 𝑥 x, so such a thing never happens. So, as the planner, you need to figure out how you can arrange this. You want to know the number of different marriage plans. Two marriage plans are considered different if at least one of the following conditions is satisfied: In one plan, a person 𝑖 i is married, and in the other, he/she is not. In one plan, a person 𝑖 i is married to 𝑗 j, and in the other, he/she is not married to 𝑗 j. As the number of plans can be quite enormous, output it modulo 998 244 353 998 244 353. 输入描述: Each test contains multiple test cases. The first line contains the number of test cases 𝑇 ( 1 ≤ 𝑇 ≤ 1 0 4 ) T (1≤T≤10 4 ) . Each test case consists of two lines. The first line contains 1 1 integer 𝑛 ( 4 ≤ 𝑛 ≤ 5 × 1 0 5 ) n (4≤n≤5×10 5 ), the number of residents in the community. It's guaranteed that 𝑛 n is even. The second line contains 𝑛 n integers 𝑎 1 , 𝑎 2 , … , 𝑎 𝑛 ( 1 ≤ 𝑎 𝑖 ≤ 𝑛 ) a 1 ​ ,a 2 ​ ,…,a n ​ (1≤a i ​ ≤n), where 𝑎 𝑖 a i ​ represents the one that the resident 𝑖 i loves. It is guaranteed that if 𝑖 ≠ 𝑗 ( 1 ≤ 𝑖 , 𝑗 ≤ 𝑛 ) i  ​ =j (1≤i,j≤n), 𝑎 𝑖 ≠ 𝑎 𝑗 a i ​  ​ =a j ​ . It is guaranteed that ∑ 𝑛 ∑n over all test cases in one test will not exceed 5 × 1 0 5 5×10 5 . 输出描述: For each test case, output 1 1 integer: the number of different marriage plans modulo 998 244 353 998 244 353. 示例1 输入 复制 2 4 1 3 4 2 6 3 4 5 6 2 1 输出 复制 3 9
07-20
<think>我们面对的错误是编译时出现:#error: The C++ Standard Library forbids macroizing the keyword "inline". Enable warning C4005 to find the forbidden define. 这个错误的原因是某个头文件或代码中定义了一个宏,该宏的名字是"inline",而C++标准库禁止对关键字(如inline)进行宏定义。 解决步骤: 1. 按照错误提示,启用警告C4005(因为C4005是宏重定义的警告,默认情况下可能未开启),这样就能找到是哪个宏定义导致了问题。 2. 在代码中(或包含的头文件中)查找将"inline"定义为宏的地方,并删除或取消该定义。 具体操作: 步骤1:启用警告C4005 在Visual Studio中,可以通过以下方式启用: - 打开项目属性 -> C/C++ -> 高级 -> 禁用特定警告,然后添加4005(注意:这里是启用警告,所以不是禁用,而是将警告级别调高,或者使用/W4) - 或者直接在代码中添加(不推荐,因为影响整个项目): #pragma warning(default:4005) - 更常见的是将警告级别调到/W4:项目属性 -> C/C++ -> 常规 -> 警告等级,设置为“启用所有警告(/W4)” 步骤2:重新编译,编译器会指出是在哪里定义了"inline"宏。 步骤3:找到问题来源后,通常有以下几种解决方式: a) 如果是自己代码中定义的,例如: #define inline __inline 或者 #define inline 那么删除或取消这个宏定义(使用#undef inline)。 b) 如果是某个第三方头文件定义的,考虑在包含该头文件之前使用预处理器指令取消该定义,例如: #undef inline 然后再包含该头文件(但要注意顺序,可能需要在包含标准库头文件之前处理)。 c) 如果无法修改第三方库,可以在包含标准库头文件之后,再包含这个有问题的头文件(因为标准库头文件在使用inline的地方已经结束,但这样不一定可靠,因为标准库头文件可能被间接包含)。 d) 如果是Windows头文件(如windows.h)引起的,请注意windows.h可能会定义一些宏,但通常不会定义inline为宏。不过,有时为了兼容旧代码,可能会定义一些关键字宏。在这种情况下,可以在包含windows.h之前定义一些宏来避免,例如: #define NOINLINE #define NOMINMAX // 避免定义min和max为宏 #include <windows.h> e) 检查是否有预处理器指令定义inline为其他关键字,例如在C代码中为了支持C99的inline而在C89中使用的技巧,但在C++中不应该这样做。 步骤4:重新编译,确保错误消失。 注意:在C++中,inline是一个关键字,任何将其定义为宏的行为都会导致未定义行为,因此必须避免。 示例: 假设错误发生在包含某个头文件"myheader.h"之后,我们可以这样处理: ```cpp // 在包含标准库头文件之前,确保没有定义inline宏 // 如果之前有定义,先取消定义 #ifdef inline #undef inline #endif #include <iostream> #include <vector> // ... 其他标准库头文件 // 然后包含有问题的头文件 #include "myheader.h" // 这个头文件内部可能会再次定义inline,但我们已经取消了,如果它再次定义,我们需要在包含它之后再次取消 // 如果"myheader.h"内部定义了inline,我们可以在包含之后再次取消 #ifdef inline #undef inline #endif ``` 然而,更好的做法是修改有问题的头文件,或者联系第三方库的维护者修复。 引用:这个错误是C++标准库(可能是头文件<xkeycheck.h>)中触发的,用于防止关键字被宏定义[^1]。 相关问题: 1. 如何防止C++中的关键字被宏定义? 2. 如何处理第三方库中的宏定义冲突? 3. 如何在Visual Studio中启用所有警告? 我们将为用户生成详细步骤。 </think>### 解决 C++ 编译错误 `#error: The C++ Standard Library forbids macroizing the keyword "inline"` 的方法 该错误表明代码中某个位置将 C++ 关键字 `inline` 定义为宏,违反了 C++ 标准库规则。以下是完整的解决步骤: --- ### 1. **定位问题宏定义** 使用编译器提示的 `C4005` 警告定位问题位置: ```cpp // 在包含标准库头文件前添加 #pragma warning(default : 4005) // 强制启用 C4005 警告 ``` 重新编译后,编译器将显示类似警告: ``` warning C4005: 'inline': macro redefinition ``` --- ### 2. **常见问题来源及解决方法 #### ▶ 情况1:Windows 头文件冲突 **问题代码**: ```cpp #include <windows.h> // 可能通过 windef.h 定义宏 #include <vector> // 标准库触发错误 ``` **解决方案**: ```cpp #define NOINLINE // 阻止 inline 宏定义 #define NOMINMAX // 可选:阻止 min/max 宏 #include <windows.h> ``` #### ▶ 情况2:第三方库定义 **问题代码**: ```cpp #include "legacy_lib.h" // 内部可能包含 #define inline __inline ``` **解决方案**: ```cpp #undef inline // 取消宏定义 #include "legacy_lib.h" ``` #### ▶ 情况3:自定义宏定义 **问题代码**: ```cpp #define inline __forceinline // 自定义宏冲突 ``` **解决方案**: ```cpp #ifdef inline #undef inline // 取消定义 #endif ``` --- ### 3. **终极解决方案:重构预处理顺序** 调整头文件包含顺序,确保标准库在可能定义宏的库之前: ```cpp // 先包含所有标准库 #include <vector> #include <algorithm> // ... 其他标准库 // 再包含可能定义宏的库 #define NOINLINE #include <windows.h> #include "legacy_lib.h" ``` --- ### 4. **永久修复建议** 在项目设置中添加全局预处理定义: 1. **Visual Studio**: - 项目属性 → C/C++ → 预处理器 → 预处理器定义 → 添加 `NOINLINE` 2. **CMake 项目**: ```cmake add_compile_definitions(NOINLINE) ``` --- ### 技术原理说明 - C++ 标准库使用 `inline` 作为关键字而非宏[^1] - Windows SDK 为兼容 C89 可能定义 `#define inline __inline`[^2] - 宏定义冲突发生在预处理阶段,与编译器无关[^3] --- ### 验证修复 编译成功后,检查是否存在内联函数: ```cpp inline void test() {} // 应正常编译 ``` > **关键提示**:修复后移除临时添加的 `#pragma warning(default:4005)`,避免过度警告干扰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值