先说现象:
- 首先:小码匠的代码在windows上是通过样例;
- 其次:我拿到她的代码,在我的mac上也跑了下,也正常通过;
我当时就感觉很纳闷,这是怎么回事呢。
注意点1:有时候macOS上能正常跑的代码,到Windows上可能直接就挂了。
之前遇到过一次,例如bool型变量你不付出值,windows和macOS默认的初始值是不同的。
这个和操作系统用的编译器有关系。
既然windows和macOS都能正常运行,那到底是啥原因呢。
我们先看下小码匠写的代码,是不是很帅气啊。
这点还是很有自信的,小码匠的码风可以秒杀95%以上oier选手。
代码语言:javascript复制#include <bits/stdc .h>
using namespace std;
const int maxn = 2e5 5;
int fa[maxn], close[maxn];
bool open[maxn];
vector<int> g[maxn];
int Find(int a) {
if (a != fa[a]) {
fa[a] = Find(fa[a]);
}
return fa[a];
}
void Union(int x, int y) {
int a = Find(x);
int b = Find(y);
if (a != b) {
fa[max(a, b)] = min(a, b);
}
}
bool same(int x, int y) {
return Find(x) == Find(y);
}
void best_coder() {
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i) {
fa[i] = i;
open[i] = true;
}
for (int i = 0; i < m; i) {
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
int k;
cin >> k;
for (int i = 0; i < k; i) {
cin >> close[i];
open[close[i]] = false;
}
int cnt = n - k;
for(int i = 0; i < n; i){
if (!open[i]) {
continue;
}
for (auto j : g[i]) {
if (open[j] && !same(i, j)) {
Union(i, j);
--cnt;
}
}
}
stack<int> ans;
ans.push(cnt);
for (int i = k - 1; i >= 0; --i) {
cnt;
open[close[i]] = true;
for (auto j : g[close[i]]) {
if (open[j] && !same(close[i], j)) {
Union(close[i], j);
--cnt;
}
}
ans.push(cnt);
}
while (!ans.empty()) {
cout << ans.top() << 'n';
ans.pop();
}
}
void happy_coder() {
}
int main() {
// 提升cin、cout效率
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// 小码匠
best_coder();
// 最优解
// happy_coder();
return 0;
}
我们截取错误日志的一部分内容
先抛出一个小问题:你能看出是什么问题吗?
代码语言:javascript复制/tmp/compiler_hvhxk0fa/src:12:25: 错误:‘int close [200005]’ redeclared as different kind of entity
12 | int fa[maxn], close[maxn];
| ^
In file included from /nix/store/79624djlfdc0a6anji2rwqd9p9ycqi8h-glibc-2.34-210-dev/include/bits/sigstksz.h:24,
from /nix/store/79624djlfdc0a6anji2rwqd9p9ycqi8h-glibc-2.34-210-dev/include/signal.h:328,
from /nix/store/bbmwawbq7wjb54fa35wr72alcm083d1f-luogu-gcc-9.3.0/include/c /9.3.0/csignal:42,
from /nix/store/bbmwawbq7wjb54fa35wr72alcm083d1f-luogu-gcc-9.3.0/include/c /9.3.0/x86_64-unknown-linux-gnu/bits/stdc .h:43,
from /tmp/compiler_hvhxk0fa/src:7:
/nix/store/79624djlfdc0a6anji2rwqd9p9ycqi8h-glibc-2.34-210-dev/include/unistd.h:358:12: 附注:previous declaration ‘int close(int)’
358 | extern int close (int __fd);
| ^~~~~
/tmp/compiler_hvhxk0fa/src: 在函数‘void best_coder()’中:
/tmp/compiler_hvhxk0fa/src:51:23: 警告:在算术表达式中使用了函数指针 [-Wpointer-arith]
51 | cin >> close[i];
说来很惭愧,我当时没有仔细看日志,一通删减代码找原因,结果搞了半天也没能查出来。
后来有点晚了,就想睡觉,突然间灵光一闪,又想看看日志到底怎么回事。
定睛一看,错误指向的是
代码语言:javascript复制close[maxn];
我当时就很纳闷,太搞了,开头定义了fa和close两个int数组,为啥close有问题呢?
代码语言:javascript复制const int maxn = 2e5 5;
int fa[maxn], close[maxn];
bool open[maxn];
vector<int> g[maxn];
回过头来我在仔细看日志
代码语言:javascript复制/tmp/compiler_hvhxk0fa/src:12:25: 错误:‘int close [200005]’ redeclared as different kind of entity
12 | int fa[maxn], close[maxn];
日志中提到【redeclared】,莫非框架底层用到这个变量了,所以重定义了。
我迅速重构代码
代码语言:javascript复制close[maxn];
改成
代码语言:javascript复制close1[maxn];
扔到洛谷上,哇塞!直接90分。
这个让我回想起之前整理过的坑。
相关的坑后面我在整理,先下个结论。
孩子们在编写代码的时候,变量名不能随便起,可能会和底层的变量重名
例如:变量名不要起成:j0, j1,很可能你本地能跑,提交就挂,这个可是0分,直接爆零,是直接爆零啊。
好啦!今天就写到这里。