主题:关于80次编程比赛,最终代码在底楼,谢谢版主帮测
Hawkxp [专家分:350] 发布于 2009-03-20 14:37:00
晚上我再重写代码,把要比较的字符串,开头有重复的字符先缩成一个字符再作比较,谢谢版主,晚上我再贴上来.
回想下线代的内容,对这题很有启发。
如果a中有一个字符比b的首字符大,那b串一定在该位置前插入,或者说,b串插入a的位置之前不能有比b首字符大的字符。。。
按这个思路考虑下去吧,你会发现这题居然是如此简单。
+++++++++++++++++++++++++++++++++++++++++++++++++
[color=FF00FF]代码已经重写过了,字典长度为4的测试文件完全通过,1楼的代码作废,当代码难以修改时,唯一的办法就是重写,请版主帮忙用100000长度的测试文件试试看,谢谢[/color]
最后更新于:2009-04-21 10:08:00
回复列表 (共23个回复)
11 楼
Hawkxp [专家分:350] 发布于 2009-03-25 09:02:00
#include <stdio.h>
#define MAXLEN 100000
//todo: 在此增加你所需要的函数或者变量或者头文件
void deal(char* a, char* b, char* c)
{
// todo: 在此补充你的处理代码
// 参数说明: a和b是输入的字符串,c要保存输出结果
long i,j,k;
long thead,twidth;
long tnum_a,tnum_b;
int flag,fend,fa,fb,fc;
flag=fend=0;
for(i=0;a[i] || flag && !fend;i++){
if(!flag){
if(a[i]>b[0]){break;}
if(a[i]==b[0]){
thead=i;twidth=tnum_a=tnum_b=1;flag=1;i++;
}
}
if(flag==1){
cycle: if(a[i] && a[i]==b[twidth] && a[i]<b[0]){
twidth++;continue;
}else if(!a[i])fend=1;
j=fa=fb=fc=0;
while(b[j%twidth]==b[twidth+j])j++;
if(b[twidth+j]>b[j%twidth])fb=2;
else if(b[twidth+j])fb=1;
tnum_b+=j/twidth;
j=0;
while(b[j%twidth]==a[i+j])j++;
if(a[i+j]>b[j%twidth])fa=2;
else if(a[i+j])fa=1;
tnum_a+=j/twidth;
if(tnum_a>tnum_b)fc=2;
else if(tnum_a<tnum_b)fc=1;
12 楼
Hawkxp [专家分:350] 发布于 2009-03-25 09:03:00
//接上楼
i=thead+twidth*tnum_a;
j=twidth*tnum_b;
for(k=0;a[i+k]==b[k] && b[k]==b[j+k] && k<twidth;k++);
if(a[i+k]==b[j+k]){
if(a[i+k]>b[k]){break;} //a=b>t
else{ //t>a=b
if(!fa){break;}
if(fc==2){i=thead;break;}
if(fc==0){
i+=k+1;
twidth*=tnum_a;
twidth+=k+1;
tnum_a=tnum_b=1;
goto cycle;
}
flag=0;
}
}else if(a[i+k]>b[j+k]){
if(b[k]>a[i+k]){ //t>a>b
if(!fb || fc==1)flag=0;
else{i=thead;break;}
}else if(b[k]==a[i+k]){ //t=a>b
if(fa==2){
if(fb)i=thead;
break;
}else if(fb && (fa==0 || fc!=1)){
i=thead;break;
}else if(fb==0 && fa==0) break;
flag=0;
}else if(b[k]>b[j+k]){ //a>t>b
if(!fb)break;
i=thead;break;
}else if(b[k]==b[j+k]){ //a>t=b
if(fb==1)i=thead;
break;
}else break; //a>b>t
}else{
if(b[k]>b[j+k]){ //t>b>a
if(fc==2 || fa==0){i=thead;break;}
flag=0;
}else if(b[k]==b[j+k]){ //t=b>a
if(fb==1 &&(fc==2 || fa==0)){i=thead;break;}
flag=0;
}else if(b[k]>a[i+k])flag=0; //b>t>a
else if(b[k]==a[i+k]){ //b>t=a
if(fa==2){break;}
flag=0;
}else break; //b>a>t
}
i--;
}
}
for(j=0;j<i;j++) c[j]=a[j];
for(j=0;b[j];j++) c[i+j]=b[j];
for(j+=i;a[i];i++) c[j++]=a[i];
c[j]='\0';
return;
}
char a[MAXLEN+1], b[MAXLEN+1], c[MAXLEN*2+1];
int main(void)
{
while (scanf("%s%s", a, b)!=EOF)
{
deal(a, b, c);
puts(c);
}
return 0;
}
13 楼
Hawkxp [专家分:350] 发布于 2009-03-25 09:05:00
代码比较丑,只是个草稿,因为不知改了N次,才通过了5个数字6位长度的测试,烦请版主再次帮测,如果结果不出错,我再整理优化一遍代码,谢谢
14 楼
Hawkxp [专家分:350] 发布于 2009-03-25 09:34:00
我用了大量的分支,就是为了减少循环比较的次数,把各种情况分得很细
我是把两个串看成波形来作比较的,事实上,当年信号处理原理俺根本没学懂,所以也没用到什么Z变换,傅里叶,频谱,只是按自己的思路来作波形的周期比较的,请各位大大不要喷我
15 楼
雨中飞燕 [专家分:18980] 发布于 2009-03-25 13:23:00
Name: "[color=Blue]Hawkxp[/color]" Problem ID "[color=Blue]135[/color]"
Submit Time: 2009/3/25-13:24
[color=red]G++: Compile Warning:
Line In function `void deal(char*, char*, char*)':
Line 12: warning: 'thead' might be used uninitialized in this function
Line 12: warning: 'twidth' might be used uninitialized in this function
Line 13: warning: 'tnum_a' might be used uninitialized in this function
Line 13: warning: 'tnum_b' might be used uninitialized in this function
[/color]
Test 1: [color=blue]Accepted[/color] Time = 0 ms
Test 2: [color=blue]Accepted[/color] Time = 0 ms
Test 3: [color=blue]Accepted[/color] Time = 81 ms
Test 4: [color=blue]Accepted[/color] Time = 18 ms
Test 5: [color=blue]Accepted[/color] Time = 336 ms
Test 6: [color=blue]Accepted[/color] Time = 73 ms
--------------------------------
Problem ID 135
Test Result [color=blue]Accepted[/color]
Total Time 508 ms
Total Memory 420 Kb / 2000 Kb
Code Length 3328 Bytes
恭喜,你是第一个pfan中能通过全部数据的人,我宣布,你就是第80次比赛的冠军,
第81次比赛将由Hawkxp主持
16 楼
雨中飞燕 [专家分:18980] 发布于 2009-03-25 13:36:00
楼主的思路很独特,所以如果楼主有时间的话,写一篇文章讲解一下你的算法思路给大家一起学习吧
17 楼
Hawkxp [专家分:350] 发布于 2009-03-25 14:03:00
嗯,主持什么的还是版主来吧,我只是来玩玩,
简单说一下体会,当b串的波形是余弦波,其波峰的最高值和a串的波峰最高值相等的时候是比较麻烦的,如果两个串(a为从比较点开始的余弦波子串)的波形是以周期的形式开始且周期重合,那么分别跳过两串的周期,将两串出周期处的波形和周期的波形,三个波形进行比较,我那代码上注释的 t>a>b,T,就是周期,根据各种情况,决定B串是插入到a的周期循环部分之前还是之后.
其中,犹以b串的波形是余弦波被幅长更大的余弦波调制成的波形最为复杂,比如:
5454545315454545315454
开始判断出54 是一个周期,找到531的时候退出的54这个周期,但如果,a串的比较部分,54的周期次数和b串的周期次数相等,出周期的部分又和b相等为531的话,事实上,这是一个更大的周期,单个周期部分为:
545454531
需要按新的周期重新判断a,b串的周期情况和出周期的位置进行比较,事实上这里就会存在一个递归,为了不增加栈空间实现递归的效果,我用了一个 goto 语句(还被小令00笑了).
我明天要出差了,可能要一周左右,等我回来时再把整理优化后的代码和详细的算法思路拿出来吧,比赛请版主主持,我对那个二值化数字图形还原的题比较有兴趣,初步的想法是把图样取样后对波形二次求导,将重复的0合为一个,就将图形的转角情况全保留下来又出除了其它的信息,但从什么地方开始取样我还没能想出来,呵呵
18 楼
雨中飞燕 [专家分:18980] 发布于 2009-03-25 14:39:00
主持也就是你出一个题目让大家练习,然后你给出改进意见或者测试结果,当然后面这一步可以边比赛边进行或者等比赛结束后再一次完成(即结束前谁也不能看到对方提交的代码),你参考一下前几次比赛就知道了
出题还是解题,大家都是玩玩,玩的过程中学到东西,又何必介意呢。你就趁出差的时间想个好题目吧
19 楼
jiang5495 [专家分:0] 发布于 2009-03-28 19:50:00
11,12楼的算法也还有完美,
最少
123 123
这组测试过不了,
应该输出112233
但程序输出的是112323
版主可以试一下.
20 楼
雨中飞燕 [专家分:18980] 发布于 2009-03-28 21:37:00
[quote]11,12楼的算法也还有完美,
最少
123 123
这组测试过不了,
应该输出112233
但程序输出的是112323
版主可以试一下.[/quote]
我试过了,是你把题目理解错
我来回复