越来越不喜欢动脑。
越来越喜欢刷水题。
取火柴游戏
Time Limit:1000MS Memory Limit:65536K
Total Submit:63 Accepted:39
Description
一堆火柴有n根,A、B两人轮流取出。每人每次可以取1到m根,最先没有火柴可取的人为败方,另一方为胜方。给出n和m,满足0 < m<= n <= 100000000,请问能否确定最终胜负,如果不能,输出“NOT SURE”,如果能,先取者必胜则输出“WIN”,先取者必败则输出“LOST”。(输出不包括双引号)
Input
Output
Sample Input
Sample Output
Source
好像有个公式的,第一个人取 n mod (m+1) 根火柴,就一定能赢。
如果 n mod (m+1)=0 那么必输
var
畅通工程续
Time Limit:1000MS Memory Limit:65536K
Total Submit:107 Accepted:26
Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M( 0 < N < 200, 0 < M < 1000 ),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X( 0 <= A, B < N,A != B,0 < X< 10000 ),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T ( 0 <= S, T < N ),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1。
Sample Input
Sample Output
Source
HDU 1874
超裸的最短路。用SPFA
但WA了几次。
因为读入是没写readln,而写read
对于多组数据。提交上去就出错了。而自己测所有数据都过了。
const
maxn=201;
var
n,m,i,s,t:longint;
a:array[0..maxn,0..maxn]of longint;
d:array[0..maxn]of longint;
q:array[0..maxn]of longint;
mark:array[0..maxn]of boolean;
procedure init;
var
i,x,y,j,z:longint;
begin
read(n,m);
for i:=0 to n-1 do
for j:=0 to n-1 do
a[i,j]:=maxlongint div 2;
for i:=1 to m do
begin
read(x,y,z);
if z a[y,x]:=a[x,y];
end;
readln(s,t);
end;
procedure main;
var
i,head,tail,x:longint;
begin
fillchar(q,sizeof(q),0);
fillchar(mark,sizeof(mark),0);
for i:=0 to n-1 do d[i]:=maxlongint div 2;
d[s]:=0;
q[1]:=s;
mark[s]:=true;
head:=1;
tail:=2;
while head<>tail do
begin
x:=q[head];
head:=head mod maxn+1;
mark[x]:=false;
for i:=0 to n-1 do
if d[x]+a[x,i]
d[i]:=a[x,i]+d[x];
if not mark[i] then
begin
mark[i]:=true;
if d[i]
head:=head-1;
if head=0 then head:=maxn;
q[head]:=i;
end
else
begin
mark[i]:=true;
q[tail]:=i;
tail:=tail mod maxn+1;
end;
end;
end;
end;
if d[t]<>maxlongint div 2 then writeln(d[t])
else writeln(-1);
end;
begin
while not eof do
begin
init;
main;
end;
end.
免费馅饼(NOI1998)
Time Limit:10000MS Memory Limit:65536K
Total Submit:78 Accepted:16
Description
[问题描述]
在一个长形舞台上,舞台的宽度为W,且W为奇数,舞台的高为H,有一个人站在舞台的底层中央,如下图所示,W=9,H=5。
游戏开始后舞台顶端格子中不断的有馅饼落下,每个馅饼由4个参数组成,即初始出现时间,水平位置,下落速度,分值。人每秒可以向左移动1格或2格,或不动,或向右移动1格或2格去接馅饼,只有当馅饼在某秒末正好落在某格中,而人也同时赶到,此时人可以接到此馅饼。例如,0,3,2,10表示第一个馅饼于0秒开始落下,水平位置为3,速度为2格/秒,分值为10,此馅饼1秒钟后落到(3,3)位置,同时人可移动到(5,3)位置,第2秒钟后,馅饼落到(5,3)位置,而人站立不动,则此时人可以接到此馅饼,而得分为10。
[问题] 当W、H及馅饼下落的全部信息给出之后,找出一个接馅饼的方案,能得到最高的分。
Input
输入文件的第一行是用空格隔开的两个正整数,分别给出了舞台的宽度W(1到99之间的奇数)和高度H(1到100之间的整数)。
接下来依馅饼的初始下落时间顺序给出了所有馅饼的信息。每一行给出了一块馅饼的信息。由四个正整数组成,分别表示了馅饼的初始下落时刻(0到1000秒),水平位置、下落速度(1到100)以及分值。游戏开始时刻为0。从1开始自左向右依次对水平方向的每格编号。输入文件中同一行相邻两项之间用一个空格隔开。
Output
一行,给出了一个正整数,表示你的程序所收集的最大分数之和。
Sample Input
Sample Output
Source
很久之前做过的。
重新刷题。
比以前快了。但复杂了。
现在的:
var
w,h,st:longint;
a:array[1..10001,1..4]of longint;
f1,f2:array[1..100+1]of longint;
t:array[0..10001,1..100]of longint;
procedure init;
var
i,j,tt,ss,vv,ww,x:longint;
begin
readln(w,h);
while not eof do
begin
read(tt,ss,vv,ww);
readln;
x:=(h-1) div vv;
if (h-1) mod vv<>0 then continue;
inc(t[tt+x,ss],ww);
if tt+x>st then st:=x+tt;
if ww=4 then exit;
end;
end;
procedure main;
var
i,j,max:longint;
begin
for i:=1 to w do f1[i]:=-1;
f1[w div 2+1]:=0;
fillchar(f2,sizeof(f2),0);
for i:=0 to st do
begin
for j:=1 to w do
begin
max:=f1[j];
if (j>2)and(f1[j-2]>max) then max:=f1[j-2];
if (j>1)and(f1[j-1]>max) then max:=f1[j-1];
if (j
if (j
if max<>-1 then f2[j]:=max+t[i,j]
else f2[j]:=-1;
end;
f1:=f2;
fillchar(f2,sizeof(f2),0);
end;
end;
procedure print;
var
i,max:longint;
begin
max:=0;
for i:=1 to w do
if f1[i]>max then max:=f1[i];
writeln(max);
end;
begin
init;
main;
print;
end.
以前的:
var
w,h,max,n:longint;
a:array[-1..100,-1..100]of longint;
f:array[-1..100,-1..100]of longint;
procedure init;
var
s,x,v,p,i:longint;
begin
readln(w,h);
h:=h-1;
while not eof do
begin
readln(s,x,v,p);
if h mod v<>0 then continue;
a[s+h div v,x]:=p+a[s+h div v,x];
if s+h div v>n then n:=s+h div v;
end;
end;
procedure main;
var
i,j,k:longint;
begin
for i:=1 to (w div 2-1) do
a[1,i]:=0;
for i:=w div 2+3 to w do
a[1,i]:=0;
f[1]:=a[1];
for i:=2 to n do
for k:=1 to w do
begin
for j:=k-2 to k+2 do
if f[i-1,j]+a[i,k]>f[i,k] then f[i,k]:=f[i-1,j]+a[i,k];
end;
for i:=1 to w do
if f[n,i]>max then max:=f[n,i];
end;
begin
init;
main;
write(max);
end.
【图论基础】有向图中任意两点最短路径(floyd)
Time Limit:10000MS Memory Limit:65536K
Total Submit:165 Accepted:73
Description
一个含n个结点的有向图(注意:是有向图!!),以矩阵存储方式给出,请求出指定的多组两个点之间的最短距离及其最短路径。
Input
第1行,一个整数n(0 < n < 300 ),表示有向图中结点的个数。
第2行到第(n+1)行,是一个n*n的矩阵,表示无向图中各结点之间的联结情况,矩阵中的数据为小于1000的正整数,其中 -1 表示无穷大!!
第(n+2)行,一个整数m,表示接下来有m组顶点 < i , j >对,其中,i是起点,j是终点,且i不等于j。
接下来有m行,每行两个整数,中间一个空格间隔,分别表示i和j,表示求解i点到j点的最短距离及最短路径。
注:输入数据已经确保答案每一组顶点间的最短路径是唯一的,无多解数据存在,顶点编号用数字表示,从1开始编号,至n结束!
Output
共 2m 行。
第(m-1)*2+1行,一个整数,表示第m组顶点的最短距离,若两点间距离为无穷大,则输出 -1。
第(m-1)*2+2行,用顶点编号表示的路径序列,各顶点编号间用一个空格间隔,表示第m组顶点的最短路径,若两点间距离为无穷大,则输出的路径序列为 -1。
Sample Input
Sample Output
Source
看这道题不顺眼很久了。因为偏偏要输出个路径。
我就先用floyd算出最短路,然后深搜路径。尽管很慢,但还是过了。
其实有更好的方法。
type
arr=array[0..300+1]of longint;
var
pan:boolean;
n,m,s,t,min:longint;
a,b:array[1..300+1,1..300+1]of longint;
mark:array[1..300+1]of boolean;
f:arr;
procedure init;
var
i,j:longint;
begin
read(n);
for i:=1 to n do
for j:=1 to n do
read(a[i,j]);
read(m);
b:=a;
end;
procedure dfs(x,w:longint);
var
i:longint;
begin
if pan then exit;
if w>min then exit;
if x=t then
begin
for i:=1 to f[0]-1 do write(f[i],' ');
writeln(f[f[0]]);
pan:=true;
exit;
end;
for i:=1 to n do
if not mark[i] then
if b[x,i]>0 then
begin
inc(f[0]);
f[f[0]]:=i;
mark[i]:=true;
dfs(i,w+b[x,i]);
mark[i]:=false;
f[f[0]]:=0;
dec(f[0]);
end;
end;
procedure main;
var
i,j,k:longint;
begin
for k:=1 to n do
for i:=1 to n do
if i<>k then
for j:=1 to n do
if (j<>k)and(j<>i) then
if ((a[i,j]>a[i,k]+a[k,j])or(a[i,j]=-1))and(a[i,k]<>-1)and(a[k,i]<>-1) then
a[i,j]:=a[i,k]+a[k,j];
for i:=1 to m do
begin
read(s,t);
min:=a[s,t];
fillchar(f,sizeof(f),0);
fillchar(mark,sizeof(mark),false);
mark[s]:=true;
f[0]:=1;
f[1]:=s;
pan:=false;
writeln(min);
if min=-1 then writeln(-1)
else
dfs(s,0);
end;
end;
begin
init;
main;
end.
核电站问题(SGOI)
Time Limit:10000MS Memory Limit:65536K
Total Submit:51 Accepted:23
Description
核电站问题
一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数。
Input
输入文件只一行,两个正整数N,M( 1 < N < 50,2 ≤ M ≤ 5 )
Output
输出文件只有一个正整数S,表示方案总数。
Sample Input
Sample Output
Source
var