基本思路是把每一个字符(1或0)看作一棵2叉树的叶结点,然后一层一层向上合并。合并规则是:如果两个都是"A",那合并为"A";两个都是"B"则合并为"B";否则就是"C"然后追加这两个字符串
在实现的过程中可以用一个队列来代替。初始化的时候把所有字符当作字符串塞进去,然后每次取出两个,处理后塞进去一个。可以证明,由于基因编码长度为2^k,因此每次取出的两个对应的原基因编码长度必定相等(就是不存在跨层合并的现象)
在做TJU1173的时候想到了一个更好的解法。具体看Kitty猫的基因编码-版本2题解
在实现的过程中可以用一个队列来代替。初始化的时候把所有字符当作字符串塞进去,然后每次取出两个,处理后塞进去一个。可以证明,由于基因编码长度为2^k,因此每次取出的两个对应的原基因编码长度必定相等(就是不存在跨层合并的现象)
#include<iostream>
using namespace std;
typedef struct item
{
char* s;
item* Next;
}item;
class Queue
{
public:
Queue();
void Push(char* s);
char* Pop();
int IsEmpty();
private:
item *front,*end;
};
void Process(char *source);
int main()
{
char s[257];
while(cin>>s)
Process(s);
return 0;
}
void Process(char *source)
{
char *s[257],*k,*i,*temp,*l,*dk,*di;
int pos = 0;
while(1)
{
s[pos] = new char[2];
s[pos][0] = *source++;
if(s[pos][0] == '\0') break;
s[pos][0] = s[pos][0] - '0' + 'A';
s[pos][1] = '\0';
pos++;
}
Queue q;
for(int j=0;j<pos;j++)
q.Push(s[j]);
while(1)
{
k = q.Pop();
if(q.IsEmpty())
{
cout<<k<<endl;
break;
}
i = q.Pop();
if(*(k+1) == '\0' && *(i+1) == '\0' && *k == *i)
{
l = k;
delete(i);
}
else
{
l = new char[512];
temp = l;
di = i; dk = k;
*temp++ = 'C';
while(*k) *temp++ = *k++;
while(*i) *temp++ = *i++;
delete(di);delete(dk);
*temp = '\0';
}
q.Push(l);
}
}
Queue::Queue(){front=end=NULL;}
void Queue::Push(char* s)
{
item* i = new item();
i->s = s;
i->Next = NULL;
if(end != NULL)
{
end->Next = i;
end = i;
}
else
front=end=i;
}
char* Queue::Pop()
{
if(front!=NULL)
{
char* s = front->s,*t=new char[512],*dt = t,*ds = s;
while(*ds) *dt++ = *ds++;
*dt = '\0';
delete(s);
item* i = front->Next;
delete(front);
front = i;
if(front == NULL) end = NULL;
return t;
}
return "";
}
int Queue::IsEmpty(){return front==NULL;}
此题的数据规模加强版是TJU1173。那题由于可用内存只有1000k,所以要思考一下内存问题的~ using namespace std;
typedef struct item
{
char* s;
item* Next;
}item;
class Queue
{
public:
Queue();
void Push(char* s);
char* Pop();
int IsEmpty();
private:
item *front,*end;
};
void Process(char *source);
int main()
{
char s[257];
while(cin>>s)
Process(s);
return 0;
}
void Process(char *source)
{
char *s[257],*k,*i,*temp,*l,*dk,*di;
int pos = 0;
while(1)
{
s[pos] = new char[2];
s[pos][0] = *source++;
if(s[pos][0] == '\0') break;
s[pos][0] = s[pos][0] - '0' + 'A';
s[pos][1] = '\0';
pos++;
}
Queue q;
for(int j=0;j<pos;j++)
q.Push(s[j]);
while(1)
{
k = q.Pop();
if(q.IsEmpty())
{
cout<<k<<endl;
break;
}
i = q.Pop();
if(*(k+1) == '\0' && *(i+1) == '\0' && *k == *i)
{
l = k;
delete(i);
}
else
{
l = new char[512];
temp = l;
di = i; dk = k;
*temp++ = 'C';
while(*k) *temp++ = *k++;
while(*i) *temp++ = *i++;
delete(di);delete(dk);
*temp = '\0';
}
q.Push(l);
}
}
Queue::Queue(){front=end=NULL;}
void Queue::Push(char* s)
{
item* i = new item();
i->s = s;
i->Next = NULL;
if(end != NULL)
{
end->Next = i;
end = i;
}
else
front=end=i;
}
char* Queue::Pop()
{
if(front!=NULL)
{
char* s = front->s,*t=new char[512],*dt = t,*ds = s;
while(*ds) *dt++ = *ds++;
*dt = '\0';
delete(s);
item* i = front->Next;
delete(front);
front = i;
if(front == NULL) end = NULL;
return t;
}
return "";
}
int Queue::IsEmpty(){return front==NULL;}
在做TJU1173的时候想到了一个更好的解法。具体看Kitty猫的基因编码-版本2题解