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.