15-Day 1

来源:互联网 发布:电脑编程软件有哪些 编辑:程序博客网 时间:2024/05/20 13:38

发一下15-Day1的题解。。

1.  合并序列(minval.pas/c/cpp) 
【问题描述】  
有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数相加可以得到 N2个和,求这 N2个和中
最小的N个。 
 

用堆维护。

先把1,1加到堆里

然后每次取堆顶元素(x,y),然后再把(x+1,y),(x,y+1)加到堆里。

因为会有重复加进去,所以要用哈希判重

程序找不到了。。


2.  抓犯人(catch.pas/c/cpp) 
【问题描述】 
有犯人越狱了! 
犯人非常狡猾,每一天他都会换一个城市藏身,同一个城市绝对不会连着待两天。比如今天在城
市a,明天就会在一个能去的城市b。“能去”的意思是a到b的路没有因为他而封锁。 
警察想知道,是否存在某一天,所有的城市都是犯人有可能出没的城市。 


就是问是否到所有城市的路径权值都可以是同一个数

可以知道如果犯人可以在n时刻出现在某个城市,那么他可以在n+2,n+4,....都出现在这个城市[沿某条道路来回走]

所以用f[i,0]表示是否能在偶数时到达第i个城市

f[i,1]表示是否能在奇数时到达第i个城市

如果所有的f[i,0]为真或所有f[i,1]为真即可(但f[i,1]肯定不会全部为真)

Code:刚开始Num没有清零只有70

const shuru='catch.in';  shuchu='catch.out';  maxn=100001;  maxm=1000001;type  pppp=recordcity,data:longint;   end;varheadlist:array[0..maxn] of longint;t,next:array[0..maxm] of longint;f:array[0..maxn,0..1] of boolean;queue:array[0..2*maxn] of pppp;ppppp,time,front,finish,i,j,k,n,m,s,x,y,num:longint;ans:boolean;procedure init;beginreadln(n,m,s);num:=0;for i:=0 to n do begin headlist[i]:=-1; f[i,0]:=false; f[i,1]:=false; end;for i:=1 to m dobeginreadln(x,y);inc(num);next[num]:=headlist[x];headlist[x]:=num;t[num]:=y;inc(num);next[num]:=headlist[y];headlist[y]:=num;t[num]:=x;end;end;procedure main;begininit;f[s,0]:=true;front:=0;finish:=1;queue[1].city:=s; queue[1].data:=0;while front<>finish dobegininc(front);x:=queue[front].city; y:=queue[front].data;i:=headlist[x];while i<>-1 dobeginif not(f[t[i],1-y]) then beginf[t[i],1-y]:=true;inc(finish);queue[finish].city:=t[i];queue[finish].data:=1-y; end;i:=next[i];end;end;ans:=true;for i:=0 to n-1 do ans:=ans and f[i,0];if ans then writeln('Yes')   else writeln('No');end;beginassign(input,shuru);reset(input);assign(output,shuchu);rewrite(output);readln(time);for ppppp:=1 to time dobeginwrite('Case ',ppppp,': ');main;end;close(input);close(output);end.

3.  收费站(cost.pas/c/cpp) 
【问题描述】 
在某个遥远的国家里,有n个城市。编号为1,2,3,……,n。  
这个国家的政府修建了 m 条双向的公路。每条公路连接着两个城市。沿着某条公路,开车从一个
 城市到另一个城市,需要花费一定的汽油。  
开车每经过一个城市,都会被收取一定的费用(包括起点和终点城市)。所有的收费站都在城市中,
在城市间的公路上没有任何的收费站。  
小红现在要开车从城市 u 到城市 v(1<=u,v<=n)。她的车最多可以装下 s 升的汽油。在出发的
时候,车的油箱是满的,并且她在路上不想加油。  
在路上,每经过一个城市,她要交一定的费用。如果她某次交的费用比较多,她的心情就会变得
很糟。所以她想知道,在她能到达目的地的前提下,她交的费用中最多的一次最少是多少。这个问题
对于她来说太难了,于是她找到了聪明的你,你能帮帮她吗?


二分交费,求最短路来判定。。最开始INF太小了就只有70分

const shuru='cost.in';  shuchu='cost.out';  maxn=10000;  maxm=100001;  INF=maxlongint;  long=1000001;vard,cost,headlist:array[0..maxn] of longint;inq:array[0..maxn] of boolean;t,next,w:array[0..maxm] of longint;queue:array[0..long] of longint;m,s,ans,mid,z,num,left,right,front,finish,u,v,i,x,y,j,k,n:longint;function max(a,b:longint):longint;beginif a>b then exit(a);exit(b);end;function min(a,b:longint):longint;beginif a<b then exit(a);exit(b);end;procedure init;beginassign(input,shuru);reset(input);assign(output,shuchu);rewrite(output);readln(n,m,u,v,s);for i:=1 to n do headlist[i]:=-1;for i:=1 to n do begin readln(cost[i]); right:=max(right,cost[i]); end;for i:=1 to m dobeginreadln(x,y,z);inc(num);next[num]:=headlist[x];headlist[x]:=num;t[num]:=y;w[num]:=z;inc(num);next[num]:=headlist[y];headlist[y]:=num;t[num]:=x;w[num]:=z;end;end;procedure spfa(data:longint);var i:longint;beginqueue[1]:=u;front:=0;finish:=1;for i:=1 to n do d[i]:=INF;d[u]:=0; fillchar(inq,sizeof(inq),false);inq[u]:=true;while front<>finish dobegininc(front);if front>long then front:=front-long;x:=queue[front];inq[x]:=false;i:=headlist[x];while i<>-1 dobeginif (cost[t[i]]<=data) and (d[t[i]]>d[x]+w[i]) then begind[t[i]]:=d[x]+w[i];if not(inq[t[i]]) then begininq[t[i]]:=true;inc(finish);if finish>long then finish:=finish-long;queue[finish]:=t[i];   end;   end;i:=next[i];end;end;end;procedure main;begininit;spfa(maxlongint);if d[v]>s then beginwriteln(-1);close(input);close(output);halt;   end;left:=max(cost[u],cost[v]); ans:=maxlongint;repeatmid:=(left+right) shr 1;spfa(mid);if d[v]<=s then beginans:=min(ans,mid);right:=mid-1;end   else left:=mid+1;until left>right;writeln(Ans);close(input);close(output);end;beginmain;end.


0 0