这题刚开始的时候没读懂题目,不知道怎么计算ancester。 后来在网上搜了别人的代码,用位操作与或和移位来实现的,
没看太明白里面的移位的规律。后来自己又想了想,感觉应该是集合运算,如果有相同的char就求交集,否则就求并集。
求并集的话肯定有一条边的cost要+1。记着每个序列按字符猪哥计算ancester,否则中间anc数组要设置为[2058][1010][20].
一遍就AC了, 思路正确,最后代码如下。
#include <stdio.h>
#include <string.h>
int intersect(char *src1, char *src2, char *dest)
{
int i, j, len1, len2, k;
len1 = strlen(src1), len2 = strlen(src2);
k = 0;
for(i=0;i<len1;i++) {
for(j=0;j<len2;j++) {
if (src2[j] == src1[i]) {
dest[k++] = src1[i];
break;
}
}
}
return k;
}
int unionsect(char *src1, char *src2, char *dest)
{
int i, j, len = strlen(src2);
char *cptr;
j = strlen(src1);
strncpy(dest, src1,j);
for(i=0;i<len;i++) {
cptr = strchr(dest, src2[i]);
if (!cptr) {
dest[j++] = src2[i];
}
}
return j;
}
int func(char *src1, char *src2, char *dest)
{
if (!intersect(src1, src2, dest)) {
unionsect(src1, src2, dest);
return 1;
}
return 0;
}
int main()
{
#ifdef LOCAL_INPUT
freopen("data", "r", stdin);
#endif
int n, l, i, j, cost;
char seq[1030][1010];
char ind[2060][20];
while(scanf("%d %d", &n, &l) &&(n || l)) {
for(i=0;i<n;i++) {
scanf("%s", seq[i]);
}
cost = 0;
for(i=0;i<l;i++) {
memset(ind, '\0', sizeof(ind));
for(j=0;j<n;j++) {
ind[j+n][0] = seq[j][i];
}
for(j=n-1;j>0;j--) {
cost += func(ind[j*2], ind[j*2+1], ind[j]);
}
printf("%c", ind[1][0]);
}
printf(" %d\n", cost);
}
return 0;
}