主题:第62次编程比赛初测&最终结果
雨中飞燕 [专家分:18980] 发布于 2008-01-20 00:25:00
原比赛帖子地址[url]http://www.programfan.com/club/post-265093.html[/url]
初测结果如下:
第一组(仅含半角字符的超短数据,200*200)
diaoxue 结果错误
plane 通过(43ms)
ws0415 超时
kingofmiaomiao 结果错误,输入字符串长为1的时候
mingda 运行时错误
yxs0001 运行时错误
华山论剑 通过(11ms)
comBoy 结果错误
第二组(仅含半角字符的中等长度数据,10000*10000)
plane 超内存
华山论剑 超时
如果你认为你的代码需要修正者(仅限列表上的ID),请尽快在本帖子提交
否则将按照上表进行冠军评选。
以下提供一个全半混合输入函数GetStringW(类似gets)
[code=c]
//////////////////////////////////////////////////////
// IsSapce,判断是否空格换行回车制表等分隔符
//////////////////////////////////////////////////////
inline int IsSapce(int c)
{return c==EOF || c==' ' || c=='\n' || c=='\t' || c=='\r';}
//////////////////////////////////////////////////////
// GetStringW, 遇到EOF返回0,否则返回1
//////////////////////////////////////////////////////
int GetStringW(wchar_t* wcpBuffer)
{
int c,d;
do{
if((d=getchar())==EOF)return 0;
}while(IsSapce(d));
for(;;++wcpBuffer)
{
c = (d?d:getchar());
if(IsSapce(c))
{*wcpBuffer=0; return c!=EOF;}
if(!(c & 0x80))
{*wcpBuffer=c; d=0; continue;}
d = getchar();
if(IsSapce(d))
{*(int*)wcpBuffer=c; return d!=EOF;}
if(d & 0x80)
{
*wcpBuffer=(d<<8)|c; d=0;
}
else
*wcpBuffer = c;
}
}
[/code]
使用时(需要包含头文件string.h和stdio.h或者ctring和iostream):
wchar_t a[100001],b[100001];
while (GetStringW(a) && GetStringW(b))
{
//你的处理代码
}
//---------------------------------------------------------
最终结果请看本帖子5楼
解题报告链接:[url]http://www.programfan.com/club/post-265964.html[/url]
最后更新于:2008-01-21 22:36:00
回复列表 (共7个回复)
沙发
plane [专家分:310] 发布于 2008-01-20 10:47:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char a[200001],b[200001];
int p[2][200001],str1[200001],str2[200001];
int main(){
int l1,l2,i,j,sum;
while(scanf("%s %s",a,b)!=EOF){
for(i=0,l1=0,l2=0,j=0;a[i]&&b[j];){
if(a[i]>127&&a[i+1]>127){
str1[l1++]=a[i]*1000+a[i+1];
i+=2;
}
else{
str1[l1++]=a[i];
i++;
}
if(b[j]>127&&b[j+1]>127){
str2[l2++]=b[j]*1000+b[j+1];
j+=2;
}
else{
str2[l2++]=b[j];
j++;
}
}
if(a[i]){
while(a[i]){
if(a[i]>127&&a[i+1]>127){
str1[l1++]=a[i]*1000+a[i+1];
i+=2;
}
else{
str1[l1++]=a[i];
i++;
}}
}
else if(b[j]){
while(b[j]){
if(b[j]>127&&b[j+1]>127){
str2[l2++]=b[j]*1000+b[j+1];
j+=2;
}
else{
str2[l2++]=b[j];
j++;
}}
}
memset(p[0],0,sizeof(int)*(l2+1));
p[1][0]=0;
int k=1;
for(i=1;i<=l1;i++){
for(j=1;j<=l2;j++){
if(str1[i-1]==str2[j-1])
p[k][j]=p[1-k][j-1]+1;
else if(p[1-k][j]>=p[k][j-1])
p[k][j]=p[1-k][j];
else
p[k][j]=p[k][j-1];
}
k=1-k;
}
printf("%d\n",p[1][l2]>p[0][l2]?p[1][l2]:p[0][l2]);
}
return 0;
}
板凳
yxs0001 [专家分:9560] 发布于 2008-01-20 10:59:00
#include <iostream>
#include <cstring>
using namespace std;
//////////////////////////////////////////////////////
// IsSapce,判断是否空格换行回车制表等分隔符
//////////////////////////////////////////////////////
inline int IsSapce(int c)
{return c==EOF || c==' ' || c=='\n' || c=='\t' || c=='\r';}
//////////////////////////////////////////////////////
// GetStringW, 遇到EOF返回0,否则返回1
//////////////////////////////////////////////////////
int GetStringW(wchar_t* wcpBuffer)
{
int c,d;
do{
if((d=getchar())==EOF)return 0;
}while(IsSapce(d));
for(;;++wcpBuffer)
{
c = (d?d:getchar());
if(IsSapce(c))
{*wcpBuffer=0; return c!=EOF;}
if(!(c & 0x80))
{*wcpBuffer=c; d=0; continue;}
d = getchar();
if(IsSapce(d))
{*(int*)wcpBuffer=c; return d!=EOF;}
if(d & 0x80)
{
*wcpBuffer=(d<<8)|c; d=0;
}
else
*wcpBuffer = c;
}
}
int MaxLen(wchar_t a[100001],wchar_t b[100001])
{
wchar_t *pa,*pb; //分别指向长短数组
int la,lb; //长短数组的长度
int *c0; //矩阵
int *c1;
int j = 0;
int lena = 0,lenb = 0;
bool aend = false,bend = false;
for(int i=0;i<100001;i++)
{
if(!aend && a[i] != 0) lena ++;
else aend = true;
if(!bend && b[i] != 0) lenb ++;
else bend = true;
if(aend && bend)
break;
}
if(lena == 0 || lenb == 0)
return 0;
//寻找短数组
if(lena>lenb)
{
pa = a;
pb = b;
la = lena;
lb = lenb;
}
else
{
pa = b;
pb = a;
la = lenb;
lb = lena;
}
//初始化
c0 = new int [lb + 1];
c1 = new int [lb + 1];
for (j=0;j<lb + 1;j++)
c0[j] = c1[j] = 0;
//计算
// if(x[i] = y[j]) c[i][j] = c[i-1][j-1] + 1
// else
// c[i][j] = max(c[i][j-1],c[i-1][j])
for(int i=1;i<=la;i++)
{
for(j=1;j<=lb;j++)
{
if(pa[i-1] == pb[j-1])
c1[j] = c0[j-1] + 1;
else
c1[j] = (c1[j-1] > c0[j] ? c1[j-1] : c0[j]);
}
for(j=0;j<=lb;j++)
{
c0[j] = c1[j];
}
}
delete c0;
delete c1;
return c1[lb];
}
int main(void)
{
wchar_t a[100001],b[100001];
while (GetStringW(a) && GetStringW(b))
{
//你的处理代码
cout<<MaxLen(a,b)<<endl;
}
return 0;
}
3 楼
华山论剑 [专家分:5310] 发布于 2008-01-20 11:41:00
根据飞燕提供的输入函数修改:
[code=c]
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define MAX_LEN 100001
int x[MAX_LEN], y[MAX_LEN];
int LCS(wchar_t *a, wchar_t *b)
{
int m = wcslen(a) - 1, n = wcslen(b) - 1;
int i, j, size = sizeof(int) * (n + 2);
memset(x, 0, size);
memset(y, 0, size);
for (i=m; i>=0; --i)
{
for (j=n; j>=0; --j)
{
if (a[i]==b[j])
x[j] = 1 + y[j+1];
else
x[j] = y[j] > x[j+1] ? y[j] : x[j+1];
}
memcpy(y, x, size);
}
return x[0];
}
int IsSapce(int c)
{
return c==EOF || c==' ' || c=='\n' || c=='\t' || c=='\r';
}
int GetStringW(wchar_t *wcpBuffer)
{
int c, d;
do
{
if ((d=getchar())==EOF)
return 0;
} while(IsSapce(d));
for (;;++wcpBuffer)
{
c = (d ? d : getchar());
if (IsSapce(c))
{
*wcpBuffer = 0;
return c != EOF;
}
if (!(c & 0x80))
{
*wcpBuffer = c; d = 0;
continue;
}
d = getchar();
if (IsSapce(d))
{
*(int*)wcpBuffer = c;
return d != EOF;
}
if (d & 0x80)
{
*wcpBuffer = (d << 8) | c;
d = 0;
}
else
*wcpBuffer = c;
}
}
int main()
{
wchar_t a[MAX_LEN], b[MAX_LEN];
while (GetStringW(a) && GetStringW(b))
printf("%d\n", LCS(a, b));
return 0;
}
[/code]
跨越不了DP方法的O(mn),无论如何都是超时。
4 楼
雨中飞燕 [专家分:18980] 发布于 2008-01-20 12:05:00
测试结果:
第一组 第二组
plane 通过(4ms) 超时
yxs0001 结果错误
华山论剑 通过(6ms) 超时
5 楼
雨中飞燕 [专家分:18980] 发布于 2008-01-20 23:00:00
因本题无人能够通过第二组数据,无人对经典DP法进行改进,
所以评比将不因各人的DP实现代码决定。
在当中,仅有一人自行写出接收全半混合输入代码并且积极修改算法
所以我决定plane是冠军,并且由他主持下一次比赛
本题解题报告本人会尽快发表,请留意。
6 楼
plane [专家分:310] 发布于 2008-01-21 09:50:00
哈哈,我很幸运。正在准备中,尽快会给出下次比赛的题目
7 楼
csea [专家分:340] 发布于 2008-01-22 12:07:00
搞不懂,是不是全角字符两个连续的ascii>127?
我来回复