JZOJ2017.08.11 C组

59 篇文章 0 订阅

T1

题目描述

镇海中学开设了很多校本选修课程,有体育类、音乐类、美术类、无线电测向、航空   航海航天模型制作等,力争使每位学生高中毕业后,能学到一门拿得出手的兴趣爱好,为将来的终身发展打下基础。在体育类的校本选修课程中,有一门课程是斯诺克台球。
斯诺克台球比赛中有21个球,其中有15个红球,6个彩球(黄、绿、棕、蓝、粉、黑)。甲乙二人轮流打球。打一个红球得1分,打一个彩球的得分如下:
黄球:2分;        绿球:3分;         棕球:4分;
蓝球:5分;        粉球:6分;         黑球:7分;
最后以得分高者为胜。
简化后的打球规则如下:
1.如果有红球,第奇数次必须打红球,打过的红球从桌面上拿走;
2.每打一个红球后,可以任意选一个彩球打,打红球后接着打的彩球不从桌面上拿走;
3 如果桌面上已经没有红球可打了,那么按照分值从小到大的次序打彩球,这时候每打一个彩球都从桌面上拿走。
打球时犯规的判罚如下:
 1.没有打中球,给对方加4分;
 2.没有按照打球规则打该打的球,即打中了错误的球时:
(1)如果这个错误的球的分值大于4,那么给对方加等于这个球的分值;
(2)如果这个错误的球的分值不大于4,那么给对方加4分;
打中的错误球不从桌面上拿走。
请统计某局比赛进行到现在为止的比分。  

思路:模拟,没啥好说。。。

代码:

uses math;
var n,m,x,t,t1,i,red,colourful:longint;
begin
  assign(input,'snooker.in');
  assign(output,'snooker.out');
  reset(input);
  rewrite(output);
  read(n,m);
  red:=15;
  colourful:=1;
  for i:=1 to n-1 do
  begin
    read(x);
    if x=1 then dec(red) else
    if (red=0)and((i mod 2=1)or(colourful>1)) then inc(colourful);
    t:=t+x;
  end;
  read(x);
  inc(i);
  if (red=0)and((i mod 2=1)or(colourful>1)) then inc(colourful);
  if x=0 then t1:=t1+4 else
  if (red=0)and(x<>colourful) then t1:=t1+max(4,x) else
  if (n mod 2=1)and(x>1)and(red<>0) then t1:=t1+max(4,x) else
  if (n mod 2=0)and(x=1) then t1:=t1+4 else
  t:=t+x;
  x:=t1; t1:=t; t:=x;
  for i:=1 to m-1 do
  begin
    read(x);
    if (x=1) then dec(red) else
    if (red=0)and((i mod 2=1)or(colourful>1)) then inc(colourful);
    t:=t+x;
  end;
  read(x);
  inc(i);
  if (red=0)and((i mod 2=1)or(colourful>1)) then inc(colourful);
  if x=0 then t1:=t1+4 else
  if (red=0)and(x<>colourful) then t1:=t1+max(4,x) else
  if (m mod 2=1)and(x>1)and(red<>0) then t1:=t1+max(4,x) else
  if (m mod 2=0)and(x=1) then t1:=t1+4 else
  t:=t+x;
  if x=1 then dec(red);
  write(t1,' ',t);
  close(input);
  close(output);
end.

T2

现在有n个人,每个人都有一个智力值和能力值。对于某一个人A来说,如果其它n-1个人中,没有人的智力值和能力值都比A高,则我们称A为“牛人”。反过来说,只要有一个人的智力值和能力值都比A高,则A就不是“牛人”了。
请统计共有多少个“牛人”。

思路:

可以看成平面直角坐标系,只要没有点在他右上角,则此店是牛人。

代码:

var a,b:array[-10..100010] of longint;
    n,i,j,ans:longint;
    f:array[-10..100010] of boolean;
    t:boolean;
procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
  if l>=r then exit;
  i:=l; j:=r; mid:=a[(i+j) div 2];
  repeat
    while a[i]<mid do inc(i);
    while a[j]>mid do dec(j);
    if i<=j then
    begin
      a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];
      b[0]:=b[i]; b[i]:=b[j]; b[j]:=b[0];
      inc(i); dec(j);
    end;
  until i>=j;
  qsort(l,j);
  qsort(i,r);
end;
begin
  assign(input,'niuren.in');
  assign(output,'niuren.out');
  reset(input);
  rewrite(output);
  read(n);
  for i:=1 to n do read(a[i]);
  for i:=1 to n do read(b[i]);
  for i:=1 to n do
  begin
    t:=true;
    if f[i] then continue;
    for j:=n downto 1 do
    begin
      if (a[i]>a[j])and(b[i]>b[j]) then f[j]:=true else
      if (a[j]>a[i])and(b[j]>b[i]) then
      begin
        t:=false;
        break;
      end;
    end;
    if t then inc(ans);
  end;
  write(ans);
  close(input);
  close(output);
end.

T3

题目描述

今年是镇海中学的百年校庆。校庆演出时,导演需要一列连续的身高递增的学生来演出一个节目。现在有一列连续排列的学生,可以从这些学生中筛选掉最多一段连续的几个学生。然后从剩下的学生中,选出连续的若干个,这些学生的身高依次连续递增。
求可以得到的身高连续递增队列的最大长度?。

思路:

dp。f[i][0..1]表示前i人是否去掉了某一段的最大值。

代码:

uses math;
var n,i,j,ans:longint;
    a:array[-10..5010] of longint;
    f:array[-10..5010,0..1] of longint;
begin
  assign(input,'queue.in');
  assign(output,'queue.out');
  reset(input);
  rewrite(output);
  read(n);
  for i:=1 to n do read(a[i]);
  for i:=1 to n do
  begin
    if a[i]>a[i-1] then
    begin
      f[i,0]:=f[i-1,0]+1;
      f[i,1]:=f[i-1,1]+1;
    end else begin f[i,0]:=1; f[i,1]:=1; end;
    for j:=1 to i-2 do
    if a[j]<a[i] then f[i,1]:=max(f[j,0]+1,f[i,1]);
    ans:=max(f[i,0],ans);
    ans:=max(f[i,1],ans);
  end;
  write(ans);
  close(input);
  close(output);
end.

T4

题目描述

2011年3月16日以来,利比亚爆发的骚乱不断升级,已严重危及到普通民众和各国在利比亚工作的人员的安全。为了尽快救出在利比亚的同胞,根据利比亚的形势,我国政府告诉每个在利比亚的公民,如何行动才能最快地到达安全的地方,然后由我国派出的飞机、轮船、汽车接回国。
假设将利比亚的地图划分为一个n行m列的长方形,待拯救的同胞小A在1行1列处,安全的目标位置在n行m列处。
利比亚是一个多沙漠的国家,经过某些位置需要消耗一定数量的食品,某些位置存储有很多很多食品。假定小A现在在位置i行j列,如果身上带有足够在新位置处需要消耗的食品的话,小A的下一个位置将到达i-1行j列、i+1行j列、i行j-1列、i行j+1列这四个位置之一,如果新位置处有食品的话,小A最多能拿一份该位置处的食品。当然如果小A已有的食品加上新位置处的一份食品数量超过小A能带食品的最高上限,小A就不能拿该位置处的食品了。
如果身上的食品不够到下一位置处的消耗,小A就不能到下一位置去,否则会面临生命危险的。当然,小A可以数次经过同一个位置,每次到此位置,都需要先消耗食品,然后可以拿一份食品(如果有的话),也就是小A可以多次到同一个地方来攒食品,也可以多次到同一个地方来消耗食品。若一个位置既要消耗食品,又可以拿食品,则小A必须先消耗食品,然后才能拿一份食品。
给出利比亚的地图,请告诉小A如何最快地从起点(1,1)走到终点(n,m)。程序只要输出最短路径长度就可以了。

思路:

记忆化搜索。f[i,j,k]表示到ij食物为k的最短路。

代码:

var a,b:array[0..201,0..201] of longint;
    f:array[0..201,0..201] of boolean;
    i,j,n,m,t,code,maxc,k,x,y,w:longint;
    c:char;
procedure dfs(x,y,dep:longint);
begin
  if not f[x,y] then exit;
  if dep>=b[x,y] then exit;
  b[x,y]:=dep;
  dfs(x+1,y,dep+1);
  dfs(x-1,y,dep+1);
  dfs(x,y+1,dep+1);
  dfs(x,y+1,dep+1);
end;
begin
  assign(input,'libyan.in');
  assign(output,'libyan.out');
  reset(input);
  rewrite(output);
  readln(n,m,t,maxc);
  for i:=1 to n do
  begin
    for j:=1 to m do
    begin
      read(c);
      if c<>'*' then f[i,j]:=true;
      if (c<>'*')and(c<>'.') then a[i,j]:=ord(c)-48;
    end;
    readln;
  end;
  readln(k);
  for i:=1 to k do begin read(x,y,w); end;
  fillchar(b,sizeof(b),127);
  dfs(1,1,0);
  write(b[n,m]);
  close(input);
  close(output);
end.

T5

题目描述

FJ 决定用他现有牛群的数据来制造一个自动分类机;它能猜测牛身上有没有斑点。不幸的是,FJ 没有很好的数据。对于他的N 头牛,他所知道的仅仅只是牛的重量,以及这头牛是否有斑点。所有的牛都有不同的重量。为了猜测一个新牛C 是否有斑点,FJ 先找到现有牛群中和新牛重量最接近的牛C’。如果这头牛有斑点,FJ 猜测新牛也有斑点;反之,新牛没有斑点。如果有两头牛和新牛重量差相等,如果有其中之一的牛有斑点,那么FJ 就猜测新牛也有斑点。FJ 用他的这种测试机在新进的一群牛身上。这批牛重量(连续整数)都在A 和B 之间(包含A;B)。请帮助他决定其中有多少牛会被分类为有斑点。注意新的机器只会从FJ 现有的牛群中比较数据,不会在他任何新牛中比较。还有注意,由于A 和B 都可能很大,你的程序如果从A B 一个一个的循环很可能跑不快。

思路:

分类讨论,注意边界情况。

代码:

uses math;
var a:array[0..50011] of longint;
    f:array[0..50011] of boolean;
    n,l,r,ans,t1:longint;
procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
  if l>=r then exit;
  i:=l; j:=r; mid:=a[(i+j) div 2];
  repeat
    while a[i]<mid do inc(i);
    while a[j]>mid do dec(j);
    if i<=j then
    begin
      a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];
      f[0]:=f[i]; f[i]:=f[j]; f[j]:=f[0];
      inc(i); dec(j);
    end;
  until i>=j;
  qsort(l,j);
  qsort(i,r);
end;
procedure init;
var st:string;
    code,i,t:longint;
begin
  readln(n,l,r);
  for i:=1 to n do
  begin
    readln(st);
    t:=pos(' ',st);
    if copy(st,1,t-1)='S' then f[i]:=true;
    val(copy(st,t+1,length(st)),a[i],code);
  end;
  qsort(1,n);
  t1:=1;
  while a[t1]<l do inc(t1);
end;
procedure main;
var i,j,t:longint;
begin
  a[0]:=0;
  f[0]:=false;
  if (f[t1])and(f[t1-1]) then ans:=ans+(a[t1]-l) else
  if f[t1-1] then
  begin
    t:=(a[t1]-a[t1-1]) div 2;
    if(a[t1-1]+t>=l) then
    ans:=ans+(a[t1-1]+t-l+1);
  end else
  if f[t1] then
  begin
    t:=(a[t1]-a[t1-1])div 2;
    if(a[t1]-t>=l)then ans:=ans+t else
    ans:=ans+a[t1]-l;
  end;
  i:=t1+1;
  while(i<n)and(a[i]<r) do
  begin
    if (f[i-1])and(f[i]) then ans:=ans+a[i]-a[i-1] else
    if f[i-1] then
    begin
      ans:=ans+(a[i]-a[i-1])div 2+1;
    end else
    if f[i] then
    begin
      ans:=ans+(a[i]-a[i-1])div 2;
    end;
    inc(i);
  end;
  if f[i-1] and f[i] then ans:=ans+r-a[i-1]+1 else
  if f[i-1] then
  begin
    t:=(a[i]-a[i-1])div 2;
    if a[i-1]+t>r then ans:=ans+r-a[i-1]+1 else
    ans:=ans+t+1;
  end else
  if f[i] then
  begin
    t:=(a[i]-a[i-1])div 2+1;
    if a[i]-t+1<=r then ans:=ans+r-a[i]+t;
  end;
end;
begin
  assign(input,'learning.in');
  assign(output,'learning.out');
  reset(input);
  rewrite(output);
  init;
  main;
  write(ans);
  close(input);
  close(output);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值