有一份代码,里面使用了优先队列,然后出现了奇怪的 RE 错误
源代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long van;
template<typename T> inline
void read(T& x) {
T f=1,b=0; char ch=getchar();
while (!isdigit(ch)) {
if (ch=='-') f=-1;
ch=getchar();
} while (isdigit(ch))
b*=10,b+=ch-'0',ch=getchar();
x=f*b; return;
}
template<typename T> inline
void print(T x) {
if (x<0) putchar('-'),x=-x;
if (x==0) return putchar('0'),void();
van st[51]={0},k=0;
while (x) st[++k]=x%10,x/=10;
for (int i=k;i;i--) putchar(st[i]+'0');
} const van MaxN=50;
van p[MaxN],n,m,k,h;
char maze[MaxN][MaxN]; van g[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
van order[6]; bool used[MaxN];
van ans=0; bool dfs_used[31][31];
van stx,sty; vector<pair<van,van> > en,elem[6];
bool in(van x,van y) {
return x>0&&y>0&&x<=n&&y<=m;
}
bool DFS(van status,char goal,van x,van y) {
dfs_used[x][y]=1;
for (int i=0;i<4;i++) {
van xx=x+g[i][0],yy=y+g[i][1];
if (!in(xx,yy)) continue;
if (dfs_used[xx][yy]) continue;
if (maze[xx][yy]==goal) return true;
if (maze[xx][yy]=='#') continue;
van id=maze[xx][yy]-'A';
if ((status&(1<<id))==0&&maze[xx][yy]>='A'&&maze[xx][yy]<='Z') continue;
if (DFS(status,goal,xx,yy)) return true;
} return false;
}
bool judge_accepted() {
van now=0; for (int i=1;i<=k;i++) {
memset(dfs_used,0,sizeof dfs_used);
if (!DFS(now,order[i]+'A'-1,stx,sty)) return false;
now|=(1<<(order[i]-1));
} return true;
}
van dis[MaxN][MaxN]; bool dijk_used[31][31];
priority_queue<pair<van,pair<van,van> > > q;
van Dijkstra(van status,van harm,van goal,van lst) {
vector<van> d; assert(q.size()==0);
if (lst!=-1) for (int i=0;i<elem[lst].size();i++) {
van x=elem[lst][i].first,y=elem[lst][i].second;
d.push_back(dis[x][y]);
} memset(dijk_used,0,sizeof dijk_used);
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) dis[i][j]=-1e18;
if (lst==-1) {
dis[stx][sty]=h;
q.push(make_pair(h,make_pair(stx,sty)));
} else for (int i=0;i<elem[lst].size();i++) {
if (d[i]==-1e18) continue;
van x=elem[lst][i].first,y=elem[lst][i].second;
q.push(make_pair(d[i],make_pair(x,y)));
} while (!q.empty()) {
van nowx=q.top().second.first,nowy=q.top().second.second;
van nowh=q.top().first; q.pop();
if (dijk_used[nowx][nowy]) continue;
dijk_used[nowx][nowy]=1;
for (int i=0;i<4;i++) {
van xx=nowx+g[i][0],yy=nowy+g[i][1];
if (!in(xx,yy)) continue;
if (maze[xx][yy]=='#') continue;
van id=maze[xx][yy]-'A';
if ((status&(1<<id))==0&&maze[xx][yy]!=goal+'A'&&
maze[xx][yy]>='A'&&maze[xx][yy]<='Z') continue;
van nxth=nowh-((harm&(1<<id))!=0);
if (nxth>dis[xx][yy]) {
dis[xx][yy]=nxth;
if (maze[xx][yy]==goal+'A') continue;
q.push(make_pair(nxth,make_pair(xx,yy)));
}
}
} van l=-1e18;
for (int i=0;i<elem[goal].size();i++) {
van x=elem[goal][i].first,y=elem[goal][i].second;
l=max(l,dis[x][y]);
} return l;
}
bool is_ok(van harm) {
van now=0; for (int i=1;i<=k;i++) {
van lsth=Dijkstra(now,harm,order[i]-1,order[i-1]-1);
for (int j=0;j<en.size();j++) {
van x=en[j].first,y=en[j].second;
if (dis[x][y]>0) return true;
} now|=(1<<(order[i]-1));
} Dijkstra(now,harm,0,order[k]-1);
for (int i=0;i<en.size();i++) {
van x=en[i].first,y=en[i].second;
if (dis[x][y]>0) return true;
} return false;
}
void solver() {
van tmp=0;
if (!judge_accepted()) return;
for (int i=0;i<(1<<k);i++) {
bool x=is_ok(i);
if (x) tmp+=p[i];
} ans=max(ans,tmp);
}
void status_counter(van now=1) {
if (now>k) return solver(),void();
for (int i=1;i<=k;i++) {
if (used[i]) continue;
order[now]=i; used[i]=1;
status_counter(now+1);
used[i]=0; order[now]=0;
}
}
int main() {
read(n),read(m),read(k),read(h);
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) cin>>maze[i][j];
for (int i=0;i<(1<<k);i++) read(p[i]);
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) {
if (maze[i][j]=='$') stx=i,sty=j;
if (maze[i][j]=='@') en.push_back(make_pair(i,j));
if (maze[i][j]=='#') continue;
elem[maze[i][j]-'A'].push_back(make_pair(i,j));
} status_counter(); van S=0;
for (int i=0;i<(1<<k);i++) S+=p[i];
printf("%.3f\n",double(ans)/double(S));
return 0;
}
在样例较小的时候会爆出如下错误:
(gdb) r
Starting program: /home/littleyang0531/maze
munmap_chunk(): invalid pointer
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007fff7faea859 in __GI_abort () at abort.c:79
#2 0x00007fff7fb5529e in __libc_message (action=action@entry=do_abort,
fmt=fmt@entry=0x7fff7fc7f298 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#3 0x00007fff7fb5d32c in malloc_printerr (
str=str@entry=0x7fff7fc811e0 "munmap_chunk(): invalid pointer") at malloc.c:5347
#4 0x00007fff7fb5d57c in munmap_chunk (p=<optimized out>) at malloc.c:2830
#5 0x0000555555558b6a in __gnu_cxx::new_allocator<std::pair<long long, long long> >::deallocate (this=0x5555555601c0 <elem>, __p=0x555555578350)
at /usr/include/c++/9/ext/new_allocator.h:128
#6 0x0000555555557d8c in std::allocator_traits<std::allocator<std::pair<long long, long long> > >::deallocate (__a=..., __p=0x555555578350, __n=2)
at /usr/include/c++/9/bits/alloc_traits.h:469
#7 0x0000555555557220 in std::_Vector_base<std::pair<long long, long long>, std::allocator<std::pair<long long, long long> > >::_M_deallocate (
this=0x5555555601c0 <elem>, __p=0x555555578350, __n=2)
at /usr/include/c++/9/bits/stl_vector.h:351
#8 0x0000555555556b24 in std::_Vector_base<std::pair<long long, long long>, std::allocator<std::pair<long long, long long> > >::~_Vector_base (
this=0x5555555601c0 <elem>, __in_chrg=<optimized out>)
at /usr/include/c++/9/bits/stl_vector.h:332
#9 0x0000555555556b79 in std::vector<std::pair<long long, long long>, std::allocator<std::pair<long long, long long> > >::~vector (this=0x5555555601c0 <elem>,
__in_chrg=<optimized out>) at /usr/include/c++/9/bits/stl_vector.h:680
#10 0x0000555555556845 in __tcf_0 () at maze.cpp:26
#11 0x00007fff7fb0e8d7 in __run_exit_handlers (status=0,
listp=0x7fff7fcb4718 <__exit_funcs>,
run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true)
at exit.c:108
#12 0x00007fff7fb0ea90 in __GI_exit (status=<optimized out>) at exit.c:139
#13 0x00007fff7faec0ba in __libc_start_main (main=0x555555556474 <main()>, argc=1,
argv=0x7fffffffe4e8, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffe4d8) at ../csu/libc-start.c:342
#14 0x000055555555528e in _start ()
最后的结果是能出正确结果但是在最后 RE 了,GDB 并没有返回任何与源代码有关的错误(但还是隐隐约约能够看出是和优先队列有关的错误)
在样例较大的时候会爆出如下错误:
(gdb) r
Starting program: /home/littleyang0531/maze
maze: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007fff7faea859 in __GI_abort () at abort.c:79
#2 0x00007fff7fb5d30a in __malloc_assert (
assertion=assertion@entry=0x7fff7fc818a8 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)",
file=file@entry=0x7fff7fc7d3d6 "malloc.c", line=line@entry=2379,
function=function@entry=0x7fff7fc82030 <__PRETTY_FUNCTION__.13066> "sysmalloc")
at malloc.c:298
#3 0x00007fff7fb5f96f in sysmalloc (nb=nb@entry=32,
av=av@entry=0x7fff7fcb4b80 <main_arena>) at malloc.c:2379
#4 0x00007fff7fb607c3 in _int_malloc (av=av@entry=0x7fff7fcb4b80 <main_arena>,
bytes=bytes@entry=24) at malloc.c:4141
#5 0x00007fff7fb62184 in __GI___libc_malloc (bytes=24) at malloc.c:3058
#6 0x00007fff7fd7fb39 in operator new(unsigned long) ()
from /lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x000055555555a2cf in __gnu_cxx::new_allocator<std::pair<long long, std::pair<long long, long long> > >::allocate (this=0x555555565460 <q>, __n=1)
at /usr/include/c++/9/ext/new_allocator.h:114
#8 0x0000555555559f1a in std::allocator_traits<std::allocator<std::pair<long long, std::pair<long long, long long> > > >::allocate (__a=..., __n=1)
at /usr/include/c++/9/bits/alloc_traits.h:443
#9 0x0000555555559afa in std::_Vector_base<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::_M_allocate (this=0x555555565460 <q>, __n=1)
at /usr/include/c++/9/bits/stl_vector.h:343
#10 0x0000555555558e95 in std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::_M_realloc_insert<std::pair<long long, std::pair<long long, long long> > > (
this=0x555555565460 <q>,
__position=non-dereferenceable iterator for std::vector)
at /usr/include/c++/9/bits/vector.tcc:440
#11 0x00005555555582b4 in std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::emplace_back<std::pair<long long, std::pair<long long, long long> > > (
this=0x555555565460 <q>) at /usr/include/c++/9/bits/vector.tcc:121
#12 0x000055555555793a in std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >::push_back (this=0x555555565460 <q>, __x=...)
at /usr/include/c++/9/bits/stl_vector.h:1201
#13 0x0000555555556ee8 in std::priority_queue<std::pair<long long, std::pair<long lon--Type <RET> for more, q to quit, c to continue without paging--
g, long long> >, std::vector<std::pair<long long, std::pair<long long, long long> >, std::allocator<std::pair<long long, std::pair<long long, long long> > > >, std::less<std::pair<long long, std::pair<long long, long long> > > >::push (
this=0x555555565460 <q>, __x=...) at /usr/include/c++/9/bits/stl_queue.h:637
#14 0x000055555555598a in Dijkstra (status=0, harm=0, goal=0, lst=-1) at maze.cpp:61
#15 0x0000555555556115 in is_ok (harm=0) at maze.cpp:93
#16 0x000055555555633f in solver () at maze.cpp:109
#17 0x00005555555563c9 in status_counter (now=4) at maze.cpp:115
#18 0x000055555555643b in status_counter (now=3) at maze.cpp:119
#19 0x000055555555643b in status_counter (now=2) at maze.cpp:119
#20 0x000055555555643b in status_counter (now=1) at maze.cpp:119
#21 0x0000555555556778 in main () at maze.cpp:132
这次是连结果都不出了,而且 GDB 明显指向了优先队列插入时的错误
还有在开 O2 运行的时候并没有任何问题
求助这种问题如何解决(我的代码并不是原题的正解代码)
如果有需要,原题链接: P2489