CodeVS1636 向量加法化简

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.

你可能感兴趣的:(CodeVS1636 向量加法化简)