• Codeforces Round #260 (Div. 2)


    A. Laptops

    题意:给两个数列,问是否存在i,j,是的a[i]<a[j] 而 b[i]>b[j]

    题解:先把一维排序,就是问是否存在逆序对。我写了个树状数组。。。貌似从a小到大扫一遍保存遇到的b的最大值即可

    代码:

     1 var s,a,b,c:array[0..150000] of longint;
     2     i,n,m,tot:longint;
     3 procedure sort(l,r:longint);
     4  var i,j,x,y:longint;
     5  begin
     6  i:=l;j:=r;x:=a[(i+j)>>1];
     7  repeat
     8   while a[i]<x do inc(i);
     9   while a[j]>x do dec(j);
    10   if i<=j then
    11    begin
    12    y:=a[i];a[i]:=a[j];a[j]:=y;
    13    y:=b[i];b[i]:=b[j];b[j]:=y;
    14    inc(i);dec(j);
    15    end;
    16  until i>j;
    17  if i<r then sort(i,r);
    18  if j>l then sort(l,j);
    19  end;
    20 procedure init;
    21  begin
    22  readln(n);
    23  for i:=1 to n do readln(a[i],b[i]);
    24  sort(1,n);
    25  tot:=0;
    26  i:=0;tot:=0;
    27  for i:=1 to n do
    28   begin
    29   if (i=1) or (a[i]<>a[i-1]) then
    30    begin
    31    inc(tot);c[tot]:=b[i];
    32    end;
    33   if b[i]>c[tot] then c[tot]:=b[i];
    34   end;
    35  end;
    36 procedure add(x:longint);
    37  begin
    38  while x<=n do
    39   begin
    40   inc(s[x]);
    41   inc(x,x and (-x));
    42   end;
    43  end;
    44 function sum(x:longint):longint;
    45  var t:longint;
    46  begin
    47  t:=0;
    48  while x>0 do
    49   begin
    50   inc(t,s[x]);
    51   dec(x,x and (-x));
    52   end;
    53  exit(t);
    54  end;
    55 
    56 function check:boolean;
    57  begin
    58  fillchar(s,sizeof(s),0);
    59  for i:=tot downto 1 do
    60    begin
    61    if sum(c[i]-1)>0 then exit(true);
    62    add(c[i]);
    63    end;
    64  exit(false);
    65  end;
    66 begin
    67   init;
    68   if check then writeln('Happy Alex') else writeln('Poor Alex');
    69 end.
    View Code

    B. Fedya and Maths

    题意:求 (1^n+2^n+3^n+4^n) mod 5

    题解:不难看出,4 mod 5=-1  3 mod 5=-2

          i) 当n为奇数时  有  (1^n+2^n+3^n+4^n) mod 5=(1^n+(-1)^n+2^n+(-2)^n) mod 5=0 正好抵消

          ii)当n为偶数时,(1^n+2^n+3^n+4^n) mod 5=(1+1+2^n+2^n) mod 5 =(2+2*(-1)^n/2) 所以又要分情况

               ① n/2为奇数时, 原式=2-2=0

               ② n/2为偶数时,原式=2+2=4

         所以总结起来就是如果能被4整除,=4 else =0

    代码:

    1 var z:longint;s:ansistring;
    2 begin
    3   readln(s);
    4   if length(s)>=2 then val(copy(s,length(s)-1,2),z)
    5   else val(s,z);
    6   if  z mod 4=0 then writeln(4)
    7   else writeln(0);
    8 end.     
    View Code

    C. Boredom

    题意:给一个数列,你如果选了a[k],那么a[k]+1与a[k]-1都不能选了,选a[k]获得的收益为a[k]*a[k]出现的次数,求最大收益

    题解:显然不能只选奇数或只选偶数 如 1 1 1 1 2 3 4 当然应该选1 和 4

    所以我们应该DP,令f[i]表示选i 可以获得的最大收益,g[i]表示不选i 获得的最大收益,则:

    f[i]=g[i-1]+w[i] g[i]=max(g[i-1],f[i-1])

    代码:

     1 var f,g,v,a:array[-1..150000] of int64;
     2     i,n,x:longint;
     3     function max(x,y:int64):int64;
     4      begin
     5        if x>y then exit(x) else exit(y);
     6      end;
     7 
     8 procedure init;
     9  begin
    10    readln(n);
    11    for i:=1 to n do read(a[i]);
    12    for i:=1 to n do inc(v[a[i]]);
    13  end;
    14 procedure main;
    15  begin
    16    fillchar(f,sizeof(f),0);
    17    fillchar(g,sizeof(g),0);
    18    for i:=1 to 100000 do
    19     if v[i]=0 then begin f[i]:=f[i-1];g[i]:=g[i-1];end
    20     else
    21      begin
    22        f[i]:=max(f[i-2],g[i-1])+i*v[i];
    23        g[i]:=max(g[i-1],f[i-1]);
    24      end;
    25    writeln(max(f[100000],g[100000]));
    26  end;
    27 
    28 begin
    29   init;
    30   if n=1 then writeln(a[1]) else main;
    31 end.                      
    View Code

    D. A Lot of Games
    题意:给你一些串,两个人轮流在一个字符串后面添加字母(初始为空),每个时刻都必须使当前的字符串为所有给定的字符串中的某个或多个的前缀。

    无法填字母者输。游戏一共进行K次,每次的loser将下一次first,请问先手必胜还是后手必胜?

    题解:我的想法是这样的,但是WA了,不知道哪里错了

    先把所有的字符串建成一棵trie树,使用布尔变量来表示每个节点是必胜状态还是必败状态,可以通过一次dfs求出

    定义0节点为初始节点,它的后继有 ab。。z然后分情况讨论:

    i)如果0的后继中只有必败状态,那么first将一直输到第k轮

    ii)如果0的后继中只有必胜状态,那么赢家依次是 first,second,first,second。。。最后赢家由k的就来决定

    iii)如果0的后继中既有必胜状态又有必胜状态,那么first可以选择一直输到第k-1轮,然后赢掉第k场比赛

    官方的题解是这样的:

    To solve this problem we need the prefix tree(trie), which will have all the strings from the group. Next we will calculate the two DP: win[v] — Can player win if he makes a move now (players have word equal to prefix v in the prefix tree(trie)). lose[v] — Can player lose if he makes a move now (players have word equal to prefix v in the prefix tree(trie)).

    if v is leaf of trie, then win[v] = false; lose[v] = true;

    Else win[v] = (win[vor (not win[i])); lose[v] = (lose[vor (not lose[i])), such i — children of vertex v.

    Let's look at a few cases:

    If win[v] = false, then second player win (first player lose all games).

    If win[v] = true и lose[v] = true, then first player win (he can change the state of the game in his favor).

    If win[v] = true and lose[v] = false, then if , then first player win, else second player win.

    Asymptotics — .

    代码:

    1.我的 WA了

     1 const maxn=50000+100;
     2 var s:ansistring;
     3     f:array[0..maxn,0..30] of longint;
     4     sg,flag:array[0..30*maxn] of boolean;
     5     i,n,tot,k:longint;
     6     can1,can2:boolean;
     7 procedure insert;
     8  var x,y,i:longint;
     9  begin
    10    readln(s);x:=0;
    11    for i:=1 to length(s) do
    12     begin
    13      y:=ord(s[i])-ord('a')+1;
    14      if f[x,y]=0 then
    15       begin
    16         inc(tot);
    17         f[x,y]:=tot;
    18       end;
    19      x:=f[x,y];
    20     end;
    21    flag[x]:=true;
    22  end;
    23 procedure init;
    24  begin
    25    readln(n,k);tot:=0;
    26    for i:=1 to n do insert;
    27  end;
    28 procedure dfs(x:longint);
    29  var can:boolean;i:longint;
    30  begin
    31    if flag[x] then begin sg[x]:=true;exit;end;
    32    can:=false;
    33    for i:=1 to 26 do
    34     if f[x,i]<>0 then
    35      begin
    36        dfs(f[x,i]);
    37        if not(sg[f[x,i]]) then can:=true;
    38      end;
    39    sg[x]:=can;
    40  end;
    41 function check:string;
    42  begin
    43    dfs(0);
    44    can1:=false;can2:=false;
    45    for i:=1 to 26 do
    46     if f[0,i]<>0 then
    47      if sg[f[0,i]] then can1:=true else can2:=true;
    48    if can1 and can2 then exit('First');
    49    if can1 and not(can2) then
    50      begin
    51        if  odd(k) then exit('First') else exit('Second');
    52      end;
    53    if can2 and not(can1) then exit('Second');
    54  end;
    55 begin
    56  init;
    57  writeln(check);
    58 end.                       
    View Code

    2.官方标程

     1 var
     2   s : array [0..1000000] of ansistring;
     3   f,g : array [0..1000000] of longint;
     4   a : array [0..200000,'a'..'z'] of longint;
     5   k,n,i,v : longint;
     6   procedure give(x : longint);
     7    begin
     8     if x=1 then writeln('First')
     9     else writeln('Second');
    10    end;
    11   procedure dfs1(x : longint);
    12   var
    13   i : char;
    14   v,s : longint;
    15    begin
    16     s:=0;
    17     v:=0;
    18     for i:='a' to 'z' do
    19      if a[x,i]<>0 then dfs1(a[x,i]);
    20     for i:='a' to 'z' do
    21      if a[x,i]<>0 then begin inc(v); s:=s+f[a[x,i]]; end;
    22     if v-s>0 then f[x]:=1
    23     else f[x]:=0;
    24    end;
    25   procedure dfs2(x : longint);
    26   var
    27   i : char;
    28   v,s : longint;
    29    begin
    30     v:=0;
    31     s:=0;
    32     for i:='a' to 'z' do
    33      if a[x,i]<>0 then dfs2(a[x,i]);
    34     for i:='a' to 'z' do
    35      if a[x,i]<>0 then begin inc(v); s:=s+g[a[x,i]]; end;
    36     if v=0 then g[x]:=1
    37     else
    38     if v-s>0 then g[x]:=1
    39     else g[x]:=0;
    40    end;
    41   procedure add(s : ansistring);
    42   var
    43   vr,i : longint;
    44    begin
    45     vr:=1;
    46     for i:=1 to length(s) do
    47      begin
    48       if a[vr,s[i]]=0 then begin inc(v); a[vr,s[i]]:=v; end;
    49       vr:=a[vr,s[i]];
    50      end;
    51    end;
    52 begin
    53   readln(n,k);
    54   v:=1;
    55   for i:=1 to n do readln(s[i]);
    56   for i:=1 to n do add(s[i]);
    57   dfs1(1);
    58   dfs2(1);
    59   if k=1 then give(f[1])
    60   else
    61   if f[1]=0 then give(f[1])
    62   else
    63   if g[1]=1 then give(f[1])
    64   else
    65   if k mod 2=1 then give(1)
    66   else give(0);
    67 end.
    View Code

    E题是神题,看起来就不可做。。。

  • 相关阅读:
    c++ 迷宫问题
    linux下恢复删除的文件
    c++ 分解数2
    c++ 平分石头
    多态
    设计模式中类的6种关系
    工厂方法模式
    设计原则之面向接口编程
    封装、继承
    便利构造器、单件模式
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3916301.html
Copyright © 2020-2023  润新知