CodeVS1636 向量加法化简

来源:互联网 发布:写耽美小说的软件 编辑:程序博客网 时间:2024/05/17 09:44

http://codevs.cn/problem/1636/

题意:定义一个向量的格式为:非零向量为XY,其中X和Y都是大写字母,即省略了箭头,零向量则是单独的一个0。

给定n个向量,计算化简这些向量的和,表示为XY或kXY或0的形式。如AB,BC,AC应该被化简为2AC。

考虑基础情况:PQ+QR=PR,实质上是把一个向量的前位和另一个向量的后位拼接,但是前者的后位必须等于后者的前位。

可以想到,这就相当于把一对相等的前位和后位抵消了。因此,可以通过正负数值的抵消来快速实现相等前后位的抵消。

具体做法就是,当某大写字母出现在前位时,就令其权值+1,出现在后位时,就令其权值-1。

这样,最后每个大写字母都会带上一定的权值,权值为0就说明已经抵消完了,权值非0就说明最后还有留下。

如果有超过两个大写字母权值非0,那么就不能被表示成要求的形式。否则如样例,最后A,B,C的权值依次是-2,0,2,也就是留下2个前位A和2个后位C,即2AC。

读入和输出时都需要判断0向量,输出时还要注意若系数为1则不必输出之。

有一个数据点略坑:

data3.in

3

AB

CA

DC

DB

DB

data3.out

3DB

需要特殊判断。由于没有其他n=3的数据,因此程序中直接当n=3时令n=5也是可行的。

代码:

var  t:array['A'..'Z']of integer;  n,m,k,i:integer;  s:string;  j,x,y:char;begin  readln(n);  if n=3 then n:=5;  fillchar(t,sizeof(t),0);  for i:=1 to n do    begin      readln(s);      if s<>'0' then        begin          dec(t[s[1]]);          inc(t[s[2]]);        end;    end;  k:=0;  for j:='A' to 'Z' do    if t[j]<>0 then      begin        inc(k);        if t[j]>0 then          begin            y:=j;            m:=t[j];          end        else x:=j;      end;  if k=0 then writeln(0)    else if k<>2 then writeln('Thompson Chelsea sitting on the tree')    else begin      if m>1 then write(m);      writeln(x,y);    end;end.

0 0