zoukankan      html  css  js  c++  java
  • 20140708郑州培训第二题Impossible Game

    Impossible Game
    题目描述
    你发明了一个简单的单人电脑游戏。在开始游戏时,玩家必须输入一个长度为 K 的字
    符串,且这个字符串的元素只能为‘A’‘B’‘C’或者‘D’。每一种字符串都代表一种颜色,
    不同的字符串可能有相同的颜色,而一种字符串的颜色是由你在游戏开始前决定的。为了赢
    得这个游戏,玩家必须经过一系列操作,将起始输入的字符串转换成另一个字符串,且两个
    字符串所代表的颜色相同但构成不同。游戏规定了 N 种置换规则,每种规则由两个长度相
    同的字符串 a[i]和 b[i]表示,且 a[i]和 b[i] 也均由‘A’‘B’‘C’或者‘D’构成。玩家
    可以进行下列两种操作:
    1、 交换当前字符串中两个相邻字符。例如:你可以将子串 ABC->ACB。
    2、 如果当前字符串中的某个子串恰为 a[i],那么玩家可以将其置换为 b[i]。例如:
    置换规则为 ABC->BCD,那么你可以将子串 CABC->CBCD。
    请问最少需要多少种不同的颜色,才能让玩家无论如何操作均不能赢得游戏。
    输入格式
    第一行两个整数,K 和 N。
    接下来 N 行,每行一个字符串表示 a[i]。
    接下来 N 行,每行一个字符串表示 b[i]。
    输出格式
    输出一个整数,表示最少需要多少种不同的颜色使得玩家必败。
    样例输入
    2 2
    CA
    BC
    AD
    AC
    样例输出
    6
    数据范围与约定
    对于 30%的数据,满足 1<=N<=8。
    对于 100%的数据,满足 1<=N<=50,1<=K<=30,1<=length of a[i]=length of
    b[i]<=K。

    题解:

    首先有一个显然的结论:两个字符串如果每个字母的个数都一样,那么肯定可以通过1操作互相转化

    那么我们就用一个四元组来表示一类字符串,具体可以用当成32进制的数存储,

    当然这样的字符串个数并不都一样,可以通过组合数算出来,v[i]表示字符组成为 i 的字符串的个数

    那么如果 i 能够 通过 2操作转化到 j ,就连一条有向边(i,j)

    得到一个有向图,可能有环,那么tarjan缩点,一个scc的权值为内部所有点的权值之和

    重新构图之后,也就是求一条“最长链”,可以拓扑排序+topsort解决

    ps:要注意重构图的时候边集数组,tot,head数组,insert操作不能与第一次的混了

    代码:

      1 type node=record
      2      go,next:longint;
      3      end;
      4 var le,ri:array[0..100,0..10] of longint;
      5     a,b:array[0..100] of string;
      6     e,e2:array[0..1000000] of node;
      7     c:array[0..35,0..35] of int64;
      8     dfn,low,w,ww,www:array[0..850000] of int64;
      9     head,head2,sta,scc,q,inp:array[0..800000] of longint;
     10     i,j,k,l,p,tot,cnt,n,m,h,t,x,y:longint;
     11     tmp1,tmp2,ans,ti,top:int64;
     12     num:array[0..32,0..32,0..32] of int64;
     13   function min(x,y:int64):int64;
     14    begin
     15    if x<y then exit(x) else exit(y);
     16    end;
     17   function max(x,y:int64):int64;
     18    begin
     19    if x>y then exit(x) else exit(y);
     20    end;
     21 
     22   procedure insert(x,y:longint);
     23    begin
     24    inc(tot);
     25    e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
     26    end;
     27   procedure insert2(x,y:longint);
     28    begin
     29    inc(tot);
     30    e2[tot].go:=y;e2[tot].next:=head2[x];head2[x]:=tot;
     31    end;
     32   function jz(x,y,z:longint):int64;
     33    begin
     34     jz:=x*(n+1)*(n+1)+y*(n+1)+z;
     35    end;
     36   procedure init;
     37    begin
     38      readln(n,m);
     39      fillchar(x,sizeof(x),0);
     40      fillchar(y,sizeof(y),0);
     41      for i:=1 to m do readln(a[i]);
     42      for i:=1 to m do readln(b[i]);
     43      for i:=1 to m do
     44         for j:=1 to length(a[i]) do
     45           begin
     46             inc(le[i,ord(a[i][j])-ord('A')+1]);
     47             inc(ri[i,ord(b[i][j])-ord('A')+1]);
     48           end;
     49    end;
     50   procedure zuhe;
     51    begin
     52    c[0,0]:=1;
     53    for i:=1 to 30 do
     54      begin
     55        c[i,0]:=1;c[i,i]:=1;
     56        for j:=1 to i-1 do
     57          c[i,j]:=c[i-1,j-1]+c[i-1,j];
     58      end;
     59    end;
     60   procedure prepare;
     61    begin
     62      for i:=0 to n do
     63        for j:=0 to n do
     64          for k:=0 to n do
     65            begin
     66              l:=n-i-j-k;if l<0 then continue;
     67              tmp1:=jz(i,j,k);
     68              tmp2:=c[n,i]*c[n-i,j]*c[n-i-j,k];
     69              num[i,j,k]:=tmp1;
     70              w[tmp1]:=tmp2;
     71            end;
     72      for i:=0 to n do
     73        for j:=0 to n do
     74          for k:=0 to n do
     75            begin
     76              l:=n-i-j-k;if l<0 then continue;
     77            for p:=1 to m do
     78               if (i>=le[p,1]) and (j>=le[p,2]) and (k>=le[p,3]) and (l>=le[p,4])
     79               then insert(num[i,j,k],num[i-le[p,1]+ri[p,1],j-le[p,2]+ri[p,2],k-le[p,3]+ri[p,3]]);
     80            end;
     81   end;
     82 procedure dfs(u:longint);
     83   var i,v,x:longint;
     84    begin
     85    inc(ti);dfn[u]:=ti;low[u]:=ti;
     86    inc(top);sta[top]:=u;
     87    i:=head[u];
     88    while i<>0 do
     89     begin
     90       v:=e[i].go;
     91       if dfn[v]=0 then
     92        begin
     93          dfs(v);
     94          low[u]:=min(low[u],low[v]);
     95        end
     96       else
     97          if scc[v]=0 then low[u]:=min(low[u],dfn[v]);
     98       i:=e[i].next;
     99     end;
    100    if low[u]=dfn[u] then
    101      begin
    102        inc(cnt);
    103        repeat
    104        x:=sta[top];dec(top);
    105        scc[x]:=cnt;
    106        inc(ww[cnt],w[x]);
    107        if x=u then break;
    108        until false;
    109       end;
    110    end;
    111 procedure tarjan;
    112   begin
    113    top:=0;
    114    fillchar(dfn,sizeof(dfn),0);
    115    ti:=0;cnt:=0;
    116    for i:=0 to (n+1)*(n+1)*(n+1) do
    117      if w[i]<>0 then
    118       begin
    119         if dfn[i]=0 then dfs(i);
    120       end;
    121   end;
    122 procedure topsort;
    123   begin
    124    fillchar(inp,sizeof(inp),0);
    125    for x:=0 to (n+1)*(n+1)*(n+1) do
    126      begin
    127        i:=head[x];
    128        while i<>0 do
    129         begin
    130           y:=e[i].go;
    131           if scc[x]<>scc[y] then
    132             begin
    133               inc(inp[scc[y]]);insert2(scc[x],scc[y]);
    134             end;
    135           i:=e[i].next;
    136         end;
    137      end;
    138    h:=0;t:=0;www:=ww;
    139    for i:=1 to cnt do if inp[i]=0 then begin inc(t);q[t]:=i;end;
    140    while h<t do
    141     begin
    142     inc(h);
    143     x:=q[h];
    144     i:=head2[x];
    145     while i<>0 do
    146       begin
    147       y:=e2[i].go;
    148       dec(inp[y]);if inp[y]=0 then begin inc(t);q[t]:=y;end;
    149       www[y]:=max(www[y],www[x]+ww[y]);
    150       i:=e2[i].next;
    151       end;
    152     end;
    153   end;
    154 procedure getans;
    155  begin
    156  ans:=0;
    157  for i:=1 to cnt do ans:=max(ans,www[i]);
    158  writeln(ans);
    159  end;
    160 begin
    161   assign(input,'game.in');assign(output,'game.out');
    162   reset(input);rewrite(output);
    163   init;
    164   zuhe;
    165   prepare;
    166   tarjan;
    167   topsort;
    168   getans;
    169   close(input);close(output);
    170 end.
    171                                      
    View Code
  • 相关阅读:
    Python 循环嵌套
    python 通过序列索引迭代
    Python for 循环语句
    python 无限循环
    Python 循环语句
    Python 条件语句
    Python运算符优先级
    Python身份运算符
    Python成员运算符
    Python逻辑运算符
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3904898.html
Copyright © 2011-2022 走看看