简单题

来源:互联网 发布:linux tomcat 日志切割 编辑:程序博客网 时间:2024/05/03 05:14

越来越不喜欢动脑。

越来越喜欢刷水题。

 

取火柴游戏

Time Limit:1000MS  MemoryLimit:65536K
Total Submit:63 Accepted:39

Description

一堆火柴有n根,A、B两人轮流取出。每人每次可以取1到m根,最先没有火柴可取的人为败方,另一方为胜方。给出n和m,满足0< m<= n <=100000000,请问能否确定最终胜负,如果不能,输出“NOTSURE”,如果能,先取者必胜则输出“WIN”,先取者必败则输出“LOST”。(输出不包括双引号)

Input

Output

SampleInput

8 1

SampleOutput

LOST

Source

 

好像有个公式的,第一个人取n mod (m+1) 根火柴,就一定能赢。

如果 n mod(m+1)=0 那么必输

 

var
 n,m:longint;
begin
 read(n,m);
 if n mod (m+1)=0 then writeln('LOST')
                 else writeln('WIN');
end.

 

畅通工程续

Time Limit:1000MS  MemoryLimit: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。

SampleInput

3 30 1 10 2 31 2 10 23 10 1 11 2

SampleOutput

2-1

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 div2;
 for i:=1 to m do
  begin
  read(x,y,z);
  if z<a[x,y] thena[x,y]:=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;

 whilehead<>tail do
  begin
  x:=q[head];
  head:=head mod maxn+1;
  mark[x]:=false;

  for i:=0 to n-1 do
   ifd[x]+a[x,i]<d[i] then
    begin
   d[i]:=a[x,i]+d[x];
    if notmark[i] then
    begin
      mark[i]:=true;
      if d[i]<d[head] then
      begin
      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;

  ifd[t]<>maxlongint div 2 thenwriteln(d[t])
                           else writeln(-1);
end;

begin
 while not eof do
  begin
  init;
  main;
  end;
end.

 

免费馅饼(NOI1998)

Time Limit:10000MS  MemoryLimit: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

  一行,给出了一个正整数,表示你的程序所收集的最大分数之和。

SampleInput

3 30 1 2 5 0 2 1 31 2 1 31 3 1 4

SampleOutput

12

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) modvv<>0 then continue;
   inc(t[tt+x,ss],ww);
   if tt+x>st thenst:=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) thenmax:=f1[j-2];
   if(j>1)and(f1[j-1]>max) thenmax:=f1[j-1];
   if(j<w)and(f1[j+1]>max) thenmax:=f1[j+1];
   if(j<w-1)and(f1[j+2]>max) thenmax:=f1[j+2];
   ifmax<>-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 thenmax:=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 modv<>0 then continue;
   a[s+h div v,x]:=p+a[s+h divv,x];
   if s+h div v>nthen 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
   iff[i-1,j]+a[i,k]>f[i,k] thenf[i,k]:=f[i-1,j]+a[i,k];
  end;
 for i:=1 to w do
  if f[n,i]>max thenmax:=f[n,i];
end;

begin
 init;
 main;
 write(max);
end.

 

【图论基础】有向图中任意两点最短路径(floyd)

Time Limit:10000MS  MemoryLimit: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。

SampleInput

30 4 116 0 23 -1 022 13 2

SampleOutput

52 3 173 1 2

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]>0then
    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
   ifi<>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  MemoryLimit:65536K
Total Submit:51 Accepted:23

Description

核电站问题
  一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
  任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数。

Input

  输入文件只一行,两个正整数N,M( 1< N < 50,2 ≤ M ≤ 5 )

Output

  输出文件只有一个正整数S,表示方案总数。

SampleInput

4 3

SampleOutput

13

Source

 

var
 n,m,i:longint;
 f:array[-5..50]of longint;
begin
 read(n,m);
 f[-1]:=1;
 f[0]:=1;
 for i:=1 to n do
  f[i]:=f[i-1]*2-f[i-m-1];
 writeln(f[n]);
end.

 

 

0 0
原创粉丝点击