JZOJ2017.08.06 C组

59 篇文章 0 订阅

T1

题目描述

在12月份开始的时候,选举也开始了。每个选举区将有14个代表选出,每个选民是投票给几个政党中的某一个的,投票结束以后,用一种特殊的办法来产生代表。 首先,我们要找出所有至少获得5%选票的政党。每个政党的选票数量将被依次除以1到14,我们把得到的结果叫做每个政党的分数。 第一个代表将从得分最高的政党中产生,第二个政党将从得分第二的政党中产生,依次类推,直到所有的14名代表都产生。(说明:这里所有的分数都会是唯一的)。 写一个程序,我们给出总共的投票数量和每个政党的得票数量,最终决定每个政党中的代表人数,一些可以忽略不计的投票将不被列出,所以有可能列出的每个政党的得票数量总和小于总投票数。

输入

第一行包含一个正整数X(1<=X<=2500000),表示总共的投票数量。第二行表示一个正整数N(0<=N<=10),表示我们将要考虑的政党数量。接下来N行,每行是一个政党标识符(一个大写字母)和这个政党的得票数量。

输出

输出符合条件的政党的代表的数量。对于每个政党,输出一个政党的标识符和代表的数量。输出应该按照政党的字典序从小到大输出。

这里写图片描述

思路:

一开始没看懂题,所以没做。
这道题有一个坑,其实只要党政得票数>0就得输出 
出了这个坑就很水了。。。。。。

代码:

var x,n,i:longint;
    c:array[0..20] of char;
    b,ans:array[-10..20] of longint;
    a,p:array[-10..300] of longint;
procedure px;
var i,j:longint;
begin
  for i:=1 to n*14-1 do
    for j:=i+1 to n*14 do
      if a[i]<a[j] then
      begin
        a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];
        p[0]:=p[i]; p[i]:=p[j]; p[j]:=p[0];
      end;
end;
procedure init;
var st,s:string;
    co,i,t,j:longint;
begin
  readln(x);
  readln(n);
  for i:=1 to n do
  begin
    readln(st);
    t:=pos(' ',st);
    s:=copy(st,t+1,length(st));
    val(s,b[i],co);
    if b[i]<x/20 then begin ans[i]:=-20; b[i]:=-100000000; end;
    for j:=1 to 14 do
    begin
      a[i*14+j-14]:=b[i] div j;
      p[i*14+j-14]:=i;
    end;
    c[i]:=st[1];
  end;
end;
procedure main;
var i,j:longint;
begin
  assign(input,'dhondt.in');
  assign(output,'dhondt.out');
  reset(input);
  rewrite(output);
  init;
  px;
  for i:=1 to 14 do inc(ans[p[i]]);
  for i:=1 to n-1 do
    for j:=i+1 to n do
      if c[i]>c[j] then
      begin
        c[0]:=c[i]; c[i]:=c[j]; c[j]:=c[0];
        ans[0]:=ans[i]; ans[i]:=ans[j]; ans[j]:=ans[0];
      end;
  for i:=1 to n do
    if ans[i]>=0 then writeln(c[i],' ',ans[i]);
end;
begin
  main;
  close(input);
  close(output);
end.

T2

题目描述

Mirko不喜欢做家庭作业,所以他和Slavko打赌,输的人将为另一个人做一个月的家庭作业。Mirko设计了一个问题,如下:
在他的桌子上有一个立方体,各个面上分别有1到6这6个数字,骰子的情况如图所示。 骰子的每两个对面加起来的和一定是7,这就意味着6的对面是1,5的对面是2,4的对面是3。 Mirko将骰子放在R行C列的矩阵的左上角,这个骰子开始的时候朝上的一面数字是1,并且右边的一面数字是3。Mirko做了如下的操作: 1、他旋转骰子到右边的格子,直到骰子到达最右边的那一列。 2、然后他旋转骰子到下一行。 3、现在他旋转骰子到左边的格子,直到到达最左边的那一列。 4、和步骤2一样,他转动骰子到下一行。 Mirko转动骰子直到最后,当他转到每一个格子时,他都会记下骰子朝上一面的数,最后,他把所有的这些数都加起来。Mirko打赌认为他得到的结果肯定是正确的,请你帮助他计算一下。

输入

只有一行,包含两个整数R和C(1<=R,C<=100000),表示矩阵的大小。

输出

只有一行,表示累加的和。

这里写图片描述

思路:

找规律。
每滚四次一周期。
也可以像我一样分情况找规律,快一点但麻烦一点。

代码:

var r,c,i,m:longint;
    ans:int64;
    a:array[-10..20] of longint;
procedure mm(x:longint);
begin
  m:=r mod x;
  if m=0 then m:=x;
end;
procedure quit;
begin
  close(input);
  close(output);
  halt;
end;
begin
  assign(input,'pogodak.in');
  assign(output,'pogodak.out');
  reset(input);
  rewrite(output);
  read(r,c);
  if (r=0)or(c=0) then begin write(0); quit; end;
  case c mod 4 of
    0:
    begin
      //write((c div 4)*14*r);
      ans:=(c div 4)*14*r;
      write(ans);
      quit;
    end;
    1:
    begin
      ans:=ans+(r div 4)*14+(c div 4)*14*r;
      a[1]:=1; a[2]:=5; a[3]:=6; a[4]:=2;
      mm(4);
      for i:=1 to m do
        ans:=ans+a[i];
      write(ans);
      quit;
    end;
    2:
    begin
      ans:=ans+(r div 12)*14*6+(c div 4)*14*r;
      a[1]:=5; a[2]:=6; a[3]:=8; a[4]:=10; a[5]:=8; a[6]:=5;
      a[7]:=4; a[8]:=6; a[9]:=9; a[10]:=9; a[11]:=8; a[12]:=6;
      mm(12);
      for i:=1 to m do ans:=ans+a[i];
      write(ans); quit;
    end;
    3:
    begin
      ans:=ans-(r div 4)*14+((c+1)div 4)*14*r;
      a[1]:=-3;a[2]:=-3;a[3]:=-4;a[4]:=-4;
      mm(4);
      for i:=1 to m do
        ans:=ans+a[i];
      write(ans); quit;
    end;
  end;
  close(input);
  close(output);
end.var r,c,i,m:longint;
    ans:int64;
    a:array[-10..20] of longint;
procedure mm(x:longint);
begin
  m:=r mod x;
  if m=0 then m:=x;
end;
procedure quit;
begin
  close(input);
  close(output);
  halt;
end;
begin
 { assign(input,'pogodak.in');
  assign(output,'pogodak.out');
  reset(input);
  rewrite(output);}
  read(r,c);
  if (r=0)or(c=0) then begin write(0); quit; end;
  case c mod 4 of
    0:
    begin
      //write((c div 4)*14*r);
      ans:=(c div 4)*14*r;
      write(ans);
      quit;
    end;
    1:
    begin
      ans:=ans+(r div 4)*14+(c div 4)*14*r;
      a[1]:=1; a[2]:=5; a[3]:=6; a[4]:=2;
      mm(4);
      for i:=1 to m do
        ans:=ans+a[i];
      write(ans);
      quit;
    end;
    2:
    begin
      ans:=ans+(r div 12)*14*6+(c div 4)*14*r;
      a[1]:=5; a[2]:=6; a[3]:=8; a[4]:=10; a[5]:=8; a[6]:=5;
      a[7]:=4; a[8]:=6; a[9]:=9; a[10]:=9; a[11]:=8; a[12]:=6;
      mm(12);
      for i:=1 to m do ans:=ans+a[i];
      write(ans); quit;
    end;
    3:
    begin
      ans:=ans-(r div 4)*14+((c+1)div 4)*14*r;
      a[1]:=-3;a[2]:=-3;a[3]:=-4;a[4]:=-4;
      mm(4);
      for i:=1 to m do
        ans:=ans+a[i];
      write(ans); quit;
    end;
  end;
  close(input);
  close(output);
end.

T3

题目描述

Mirko创造了一个新的机器人并且决定去测试一下。我们可以想象测试的跑道是一个二维的空间。初始的时候,机器人在(0,0)的位置,在收到了一系列命令之后,机器人就会移动,这些命令是S,J,I,Z,每个命令代表了不同的移动方向。
具体一下,如果机器人原来在(x,y)的位置,在收到了S的命令之后,会向(x,y+1)移动,收到J之后,会向(x,y-1)移动,收到I命令之后会向(x+1,y)移动,收到Z命令之后会向(x-1,y)移动。
在这个二维空间上有N个固定的控制点,在每个命令执行之后,每个固定点就会计算自己与机器人的曼哈顿距离,然后把这些距离的总和返回给Mirko。
说明:两个点(x1,y1)和(x2,y2)的曼哈顿是|x1-x2|+|y1-y2|。

输入

第一行是正整数N(1<=N<=100000)和M(1<=M<=300000),N表示控制点的个数,M表示命令的数量。
接下来N行,每行两个整数(绝对值不大于1000000),表示控制点的坐标,有些控制点可能是相同的。接下来一行,一个长度为M的字符串(包含以上四种命令),表示机器人依次收到的命令。

输出

输出M行,每行一个整数,对于第i行,输出的是第i个命令执行以后所有控制点与机器人的曼哈顿距离之和。

吃屎

代码:

uses math;
var x,y,n,m,i,maxx,maxy,minx,miny:longint;
    ans:int64;
    a,b:array[-1000001..1000001] of longint;
    c:char;
begin
  assign(input,'robot.in');
  assign(output,'robot.out');
  reset(input);
  rewrite(output);
  readln(n,m);
  for i:=1 to n do
  begin
    readln(x,y);
    ans:=ans+abs(x)+abs(y);
    inc(a[x]); inc(b[y]);
    maxx:=max(maxx,x); maxy:=max(maxy,y);
    minx:=min(minx,x); miny:=min(miny,y);
  end;
  for i:=-1000000 to 1000000 do a[i]:=a[i-1]+a[i];
  for i:=-1000000 to 1000000 do b[i]:=b[i-1]+b[i];
  x:=0; y:=0;
  for i:=1 to m do
  begin
    read(c);
    case c of
      'S':begin ans:=ans+b[y]*2-b[maxy]; inc(y); end;
      'J':begin dec(y); ans:=ans+b[maxy]-b[y]*2; end;
      'I':begin ans:=ans+a[x]*2-a[maxx]; inc(x); end;
      'Z':begin dec(x); ans:=ans+a[maxx]-a[x]*2; end;
    end;
    writeln(ans);
  end;
  close(input);
  close(output);
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值