超级郁闷,4个方法都“Memory limit exceeded”

止戈而立 2009-03-17 12:09:17
加精
题目是这样的:
输入一个字符串,如果这个字符串是由in,input,out,output,puton,one组成,就返回YES,否则返回NO。
时间限制是1秒,内存限制16M。每个字符串长度不超过10^7个字符。


方法一:

using System;
using System.Text.RegularExpressions;

class Program
{
static void Main(string[] args)
{
int lenNum = int.Parse(Console.ReadLine());
for (int i = 0; i < lenNum; i++)
{
if (Regex.IsMatch(Console.ReadLine(), "^(?:one|out(?:put)?|in(?:put)?|puton)+$")) Console.WriteLine("YES");
else Console.WriteLine("NO");
}
}
}



方法二:
using System;
class Program
{
static void Main(string[] args)
{
int lenNum = int.Parse(Console.ReadLine());
for (int i = 0; i < lenNum; i++)
{
if (Console.ReadLine().Replace("one","").Replace("puton","").Replace("output","").Replace("input","").Replace("out","").Replace("in","")=="") Console.WriteLine("YES");
else Console.WriteLine("NO");
}
}
}



方法三:
using System;
class Program
{
static void Main(string[] args)
{
int lenNum = int.Parse(Console.ReadLine());
for (int i = 0; i < lenNum; i++)
Console.WriteLine(Judge(Console.ReadLine()));
}


static string Judge(string input)
{
int pos = 0;
for (int i = input.Length - 1; i >= 0; i--)
{
pos++;
if (pos == 1||pos==4) continue;
else if (pos == 2)
{
if (input.Substring(i, pos) == "in") pos = 0;
else continue;
}
else if (pos == 3)
{
if (input.Substring(i, pos) == "one" || input.Substring(i, pos) == "out") pos = 0;
else continue;
}
else if (pos == 5)
{
if (input.Substring(i, pos) == "input" || input.Substring(i, pos) == "puton") pos = 0;
else continue;
}
else
{
if (input.Substring(i, pos) == "output") pos = 0;
else return "NO";
}
}
if (pos==0) return "YES";
else return "NO";
}
}


方法四:
using System;
class Program
{
static void Main(string[] args)
{
int lenNum = int.Parse(Console.ReadLine());
for (int i = 0; i < lenNum; i++)
Console.WriteLine(JudgeInput(Console.ReadLine()));
}

static string JudgeInput(string input)
{
int pos = 0;
for (int i = input.Length - 1; i >= 0; i--)
{
pos++;
switch (input[i])
{
case 'p':
if (pos == 5)
{
if (input.Substring(i, 5) == "puton") pos = 0;
else pos = -1;
}
break;
case 'i':
if (pos==2||pos==5)
{
if(input.Substring(i, pos) == "in"||input.Substring(i, pos) == "input") pos = 0;
else pos = -1;
}
else pos=-1;break;
case 'o':
if (pos == 3)
{
if (input.Substring(i, pos) == "one" || input.Substring(i, pos) == "out") pos = 0;
else pos = -1;
}
else if (pos == 6)
{
if (input.Substring(i, 6) == "output") pos = 0;
else pos = -1;
}
break;
case 'n':
case 'e':
case 't':
case 'u': break;
default: pos = -1; break;
}
if (pos < 0 || pos > 7) return "NO";
}
if (pos==0) return "YES";
else return "NO";
}
}



...全文
3721 148 打赏 收藏 转发到动态 举报
写回复
用AI写文章
148 条回复
切换为时间正序
请发表友善的回复…
发表回复
ylwqhr 2009-12-28
  • 打赏
  • 举报
回复
收藏,学习!~
angusn 2009-12-02
  • 打赏
  • 举报
回复
有时间再看
wangwang1103 2009-05-21
  • 打赏
  • 举报
回复
学习了~~~~~~~~~~~~~~~~
止戈而立 2009-03-24
  • 打赏
  • 举报
回复
用StreamReader.Read()和用Console.Read()相差实在太大了。
0.218 841 KB
0.906 845 KB
止戈而立 2009-03-24
  • 打赏
  • 举报
回复
刚才试了一下。。还是没有空军快。
2517343 08:36:56
24 Mar 2009 min_jie 1102 C++ Accepted
0.046 121 KB
止戈而立 2009-03-24
  • 打赏
  • 举报
回复
[Quote=引用 144 楼 litaoye 的回复:]
有时候空间也差几K,搞不太清楚!
另外那天我发现了一个问题,不知道是什么引起的,我在while判断中,用了数组的内容

while(matrix[i,m] != 0)
{
......
}

结果内存使用一下子从1M涨到了16M,不知道谁能给解释一下。

to:min_jie ,以后碰到这类问题,大家多讨论一下,挺有收获的。
[/Quote]

这个应该是跟测试数据有关,我刚才还碰到了这样的情况,前面的测试只使用了几百K的内存,但到某一个测试数据时,内存就超限.换了一种解法才搞定.

是啊,有了你和空军还有一帮朋友的深入讨论,使得此帖变得非常有价值,个人收获很大,再次感谢!也感谢其他朋友的参与!
wuyi8808 2009-03-24
  • 打赏
  • 举报
回复
目前为止,C#的最好成绩是130楼0.171秒。

138楼的C/C++程序的成绩(0.031秒,121KB)也相当不错。
止戈而立 2009-03-24
  • 打赏
  • 举报
回复
再扩展一下,是否会更快?
readonly static int[,] numFlag = new int[,]
{
// \r i n p u t o e *
{-1,1,-1,2,-1,-1,3,-1,-1},
{-1,-1,4,-1,-1,-1,-1,-1,-1}, //1:i
{-1,-1,-1,-1,5,-1,-1,-1,-1}, //2;p
{-1,-1,6,-1,7,-1,-1,-1,-1}, //3:o
{0,1,-1,8,-1,-1,3,-1,-1}, //4:in
{-1,-1,-1,-1,-1,9,-1,-1,-1}, //5:pu
{-1,-1,-1,-1,-1,-1,-1,10,-1}, //6:on
{-1,-1,-1,-1,-1,11,-1,-1,-1}, //7:ou
{-1,-1,-1,-1,12,-1,-1,-1,-1}, //8:inp
{-1,-1,-1,-1,-1,-1,13,-1,-1}, //9:put
{0,1,-1,2,-1,-1,3,-1,-1}, //10:one
{0,1,-1,14,-1,-1,3,-1,-1}, //11:out
{-1,-1,-1,-1,-1,15,-1,-1,-1}, //12:inpu
{-1,-1,16,-1,-1,-1,-1,-1,-1}, //13:puto
{-1,-1,-1,-1,17,-1,-1,-1,-1}, //14:outp
{0,1,-1,2,-1,-1,18,-1,-1}, //15:input
{0,1,-1,2,-1,-1,3,-1,-1}, //16:puton
{-1,-1,-1,-1,-1,19,-1,-1,-1}, //17:outpu
{-1,-1,20,-1,7,-1,-1,-1,-1}, //18:inputo
{0,1,-1,2,-1,-1,21,-1,-1}, //19:output
{0,1,-1,2,-1,-1,3,22,-1}, //20:inputon
{-1,-1,23,-1,7,-1,-1,-1,-1}, //21:outputo
{0,1,-1,2,-1,-1,3,-1,-1}, //22:inputone
{0,1,-1,2,-1,-1,3,24,-1}, //23:outputon
{0,1,-1,2,-1,-1,3,-1,-1} //24:outputone
};
readonly static int[] a = { 8, 8, 8, 8, 7, 8, 8, 8, 1, 8, 8, 8, 8, 2, 6, 3, 8, 8, 8, 5, 4, 8, 8, 8, 8, 0 };
绿色夹克衫 2009-03-24
  • 打赏
  • 举报
回复
有时候空间也差几K,搞不太清楚!
另外那天我发现了一个问题,不知道是什么引起的,我在while判断中,用了数组的内容

while(matrix[i,m] != 0)
{
......
}

结果内存使用一下子从1M涨到了16M,不知道谁能给解释一下。

to:min_jie ,以后碰到这类问题,大家多讨论一下,挺有收获的。

[Quote=引用 143 楼 wuyi8808 的回复:]
引用 141 楼 min_jie 的回复:
刚才试了一下。。还是没有空军快。
2517343 08:36:56
24 Mar 2009 min_jie 1102 C++ Accepted
0.046 121 KB


同一个程序,不同次提交,运行时间可能就不一样,使用的空间是一样的。

[/Quote]
wuyi8808 2009-03-24
  • 打赏
  • 举报
回复
[Quote=引用 137 楼 yangqiang71 的回复:]
练习AC算法,试验一下,注意内存使用的情况,很少吧~~
1102 C Accepted 0.062 153 KB
[/Quote]

确实不错,但我有更强的(无论是时间还是空间):
2517304 07:35:57 24 Mar 2009 xenium9 1102 C++ Accepted 0.031 121 KB

#include <stdio.h>

const int a[] = {0,0,0,0,1,0,0,0,2,0,0,0,0,3,4,5,0,0,0,6,7,0,0,0,0,0};
const int b[][8] =
{
// * e i n o p t u
{ 15,15, 7,15, 4,11,15,15 }, // 0
{ 15,15, 7,15, 4, 8,15,15 }, // 1
{ 15,15, 7,15,10,11,15,15 }, // 2
{ 15, 0, 7,15, 4,11,15,15 }, // 3
{ 15,15,15, 5,15,15,15, 6 }, // 4
{ 15, 0,15,15,15,15,15,15 }, // 5
{ 15,15,15,15,15,15, 1,15 }, // 6
{ 15,15,15, 1,15,15,15,15 }, // 7
{ 15,15,15,15,15,15,15, 9 }, // 8
{ 15,15,15,15,15,15, 2,15 }, // 9
{ 15,15,15, 3,15,15,15, 6 }, // 10
{ 15,15,15,15,15,15,15,12 }, // 11
{ 15,15,15,15,15,15,13,15 }, // 12
{ 15,15,15,15,14,15,15,15 }, // 13
{ 15,15,15, 0,15,15,15,15 }, // 14
};

void main()
{
int c, i, n, s;
scanf("%d\n", &n);
for (i = 0; i < n; i++)
{
for (s = 0; (c = getchar()) != 10;)
{
if (s < 15) s = b[s][a[c - 97]];
}
printf(s < 4 ? "YES\n" : "NO\n");
}
}
wuyi8808 2009-03-24
  • 打赏
  • 举报
回复
[Quote=引用 141 楼 min_jie 的回复:]
刚才试了一下。。还是没有空军快。
2517343 08:36:56
24 Mar 2009 min_jie 1102 C++ Accepted
0.046 121 KB
[/Quote]

同一个程序,不同次提交,运行时间可能就不一样,使用的空间是一样的。



[Quote=引用 142 楼 min_jie 的回复:]
用StreamReader.Read()和用Console.Read()相差实在太大了。
0.218 841 KB
0.906 845 KB
[/Quote]

Console.OpenStandardInput() 是有缓冲的,而 Console 或 Console.In 可能是没有缓冲的,所以性能相差很大。
yangqiang71 2009-03-23
  • 打赏
  • 举报
回复
练习AC算法,试验一下,注意内存使用的情况,很少吧~~
1102 C Accepted 0.062 153 KB

#include <stdio.h>
//#define DEBUG
#define N 1000

int flag[30][255] = {0};
int output[30] = {0};
int out[N] = {0};

void creat_table();
int check();

int main()
{
int num;
int i;
scanf("%d\n",&num);
if (num > 1000)
{
printf("Too many lines!\n");
return -1;
}
//构造表
creat_table();
//....对算法掌握不精,手工添加...
{
flag[5]['o'] = 19;
flag[11]['o'] = 21;
flag[19]['n'] = 20;
flag[19]['u'] = 7;
flag[20]['e'] = 18;
flag[21]['n'] = 22;
flag[21]['u'] = 7;
flag[22]['e'] = 18;

output[20] = output[22] = 1;
}
#ifdef DEBUG
printf(" \te\ti\tn\to\tp\tt\tu\toutput\n");
for (i=0; i < 30; i++)
printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",i,flag[i]['e'],flag[i]['i'],flag[i]['n'],flag[i]['o'],flag[i]['p'],flag[i]['t'],flag[i]['u'],output[i]);
#endif
for (i=0; i<num; i++)
{
if (check() == -1)
out[i] = -1;
else
out[i] = 1;
}

for (i=0; out[i]!=0; i++)
{
if (out[i] == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}

void creat_table()
{
char keys[6][10] = {{"in"},{"input"},{"out"},{"output"},{"puton"},{"one"}};
int state = 1;
int i;

for (i=0; i < 6; i++)
{
int j =0,k=0;
while (keys[i][j] != '\0')
{
if (flag[k][keys[i][j]] != 0)
k = flag[k][keys[i][j]];
else
{
flag[k][keys[i][j]] = state;
k=state;
state++;
}
j++;
}
output[k] = 1;
}
}

int check()
{
int c;
int cur = 0;
while ((c = getchar()) != '\n')
{
if (flag[cur][c] != 0)
cur = flag[cur][c];
else if (output[cur] == 1)
{
if ((cur = flag[0][c]) == 0)
{
while (getchar()!='\n');
return -1;
}
}
else
{
while (getchar()!='\n');
return -1;
}
}
if (output[cur] == 0)
return -1;
return 0;
}
overcast 2009-03-23
  • 打赏
  • 举报
回复
这个题目应该就是有穷状态自动机的一个应用吧,把数据一次性读进来在用replace或者用正则表达式显然是效率低下的(无论从内存的使用还是复杂度上)

另外推荐大家一个国内的类似的网站 http://acm.pku.edu.cn/JudgeOnline/

绿色夹克衫 2009-03-23
  • 打赏
  • 举报
回复
直接写表作了一个,思路跟以前的又有些不同,也算是一种方案吧.
先将输入的字符作一个影射,包括einoptu和/r,还有一个记录是否到单词尾的状态,还有一个其他字符的影射状态,
作这么多的影射主要是为了减少调用最多的循环部分的判断。不过实际效果却并没什么提高,看来只能做为另一个思路了,
不属于主流方法


class Program
{
static void Main()
{
int[,] sJump = new int[,]
{
{-1,0,-100,-1,1,-1,2,3,-1,-1},
{-1,0,-99,-1,-1,4,-1,-1,-1,-1},
{-1,0,-98,-1,-1,5,-1,-1,-1,6},
{-1,0,-97,-1,-1,-1,-1,-1,-1,7},
{-1,1,-96,-1,1,-1,2,8,-1,-1},
{-1,0,-95,9,-1,-1,-1,-1,-1,-1},
{-1,0,-94,-1,-1,-1,-1,-1,10,-1},
{-1,0,-93,-1,-1,-1,-1,-1,11,-1},
{-1,0,-92,-1,-1,-1,-1,-1,-1,12},
{-1,1,-91,-1,1,-1,2,3,-1,-1},
{-1,1,-90,-1,1,-1,2,13,-1,-1},
{-1,0,-89,-1,-1,-1,14,-1,-1,-1},
{-1,0,-88,-1,-1,-1,-1,-1,15,-1},
{-1,0,-87,-1,-1,-1,-1,-1,-1,16},
{-1,0,-86,-1,-1,17,-1,-1,-1,-1},
{-1,1,-85,-1,1,-1,18,3,-1,-1},
{-1,0,-84,-1,-1,-1,-1,-1,19,-1},
{-1,1,-83,-1,1,-1,2,3,-1,-1},
{-1,0,-82,-1,-1,20,-1,-1,-1,6},
{-1,1,-81,-1,1,-1,18,3,-1,-1},
{-1,1,-80,9,1,-1,2,3,-1,-1}
};

int[] corresponding = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 8, 9, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0 };

int lenNum;
bool[] flag;
int currentIndex;

StreamReader sr = new StreamReader(Console.OpenStandardInput());

lenNum = int.Parse(sr.ReadLine());
flag = new bool[lenNum];

for (int i = 0; i < lenNum; i++)
{
flag[i] = true;
currentIndex = 0;

while (currentIndex > -1)
currentIndex = sJump[currentIndex, corresponding[sr.Read()]];

if (currentIndex == -1)
{
flag[i] = false;
sr.ReadLine();
}
else
{
flag[i] = sJump[currentIndex + 100, 1] == 1;
sr.Read();
}
}

for (int i = 0; i < lenNum; i++)
{
if (flag[i])
Console.WriteLine("YES");
else Console.WriteLine("NO");
}
}
}
wuyi8808 2009-03-22
  • 打赏
  • 举报
回复
楼上的程序,一字不改,选择C++提交,竟然是0.031秒:
2514506 09:48:33 22 Mar 2009 xenium9 1102 C++ Accepted 0.031 9 925 KB
绿色夹克衫 2009-03-22
  • 打赏
  • 举报
回复
刚才测试了一下,速度的提高主要依赖于StreamReader,StreamReader.Read()效率要大大超过Console.Read()
看来采用分支判断或hash倒不是影响结果的主要因素,主要瓶颈还是在输入输出的处理上!
如果有比StreamReader更好的方法,相信可以获得更好的结果!
wuyi8808 2009-03-22
  • 打赏
  • 举报
回复
用C改写,0.046秒,可见C的IO更有优势:
2514492 09:34:43 22 Mar 2009 xenium9 1102 C Accepted 0.046 9 925 KB

#include <stdio.h>
#include <stdlib.h>
#define n 10000100

char p[n];
int i, j, k, l, s, f[1001];
const int a[] = {0,0,0,0,1,0,0,0,2,0,0,0,0,3,4,5,0,0,0,6,7,0,0,0,0,0};
const int b[13][8] =
{
// * e i n o p t u
{ -1, 1,-1, 3,-1,-1, 7,-1 }, // 0
{ -1,-1,-1, 2,-1,-1,-1,-1 }, // 1
{ -1,-1,-1,-1, 0,-1,-1,-1 }, // 2
{ -1,-1, 0,-1, 4,-1,-1,-1 }, // 3
{ -1,-1,-1,-1,-1,-1, 5,-1 }, // 4
{ -1,-1,-1,-1,-1,-1,-1, 6 }, // 5
{ -1,-1,-1,-1,-1, 0,-1,-1 }, // 6
{ -1,-1,-1,-1,-1,-1,-1, 8 }, // 7
{ -1,-1,-1,-1, 0, 9,-1,-1 }, // 8
{ -1,-1,-1,10,-1,-1,11,-1 }, // 9
{ -1,-1, 0,-1,-1,-1,-1,-1 }, // 10
{ -1,-1,-1,-1,-1,-1,-1,12 }, // 11
{ -1,-1,-1,-1, 0,-1,-1,-1 }, // 12
};

void main()
{
l = fread(p, sizeof(char), n, stdin);
while (p[j] != 10) j++;
for (i = l - 2; i >= j; i--)
{
if (p[i] == 10)
{
f[k++] = s;
s = 0;
}
else if (s >= 0) s = b[s][a[p[i] - 97]];
}
for (k--; k >= 0; k--)
{
printf(!f[k] ? "YES\n" : "NO\n");
}
}
wuyi8808 2009-03-22
  • 打赏
  • 举报
回复
0.171秒的C#程序:

using System;
using System.IO;

class Timus1102
{
readonly static int[] a = {0,0,0,0,1,0,0,0,2,0,0,0,0,3,4,5,0,0,0,6,7,0,0,0,0,0};
readonly static int[,]b =
{
// * e i n o p t u
{ -1, 1,-1, 3,-1,-1, 7,-1 }, // 0
{ -1,-1,-1, 2,-1,-1,-1,-1 }, // 1
{ -1,-1,-1,-1, 0,-1,-1,-1 }, // 2
{ -1,-1, 0,-1, 4,-1,-1,-1 }, // 3
{ -1,-1,-1,-1,-1,-1, 5,-1 }, // 4
{ -1,-1,-1,-1,-1,-1,-1, 6 }, // 5
{ -1,-1,-1,-1,-1, 0,-1,-1 }, // 6
{ -1,-1,-1,-1,-1,-1,-1, 8 }, // 7
{ -1,-1,-1,-1, 0, 9,-1,-1 }, // 8
{ -1,-1,-1,10,-1,-1,11,-1 }, // 9
{ -1,-1, 0,-1,-1,-1,-1,-1 }, // 10
{ -1,-1,-1,-1,-1,-1,-1,12 }, // 11
{ -1,-1,-1,-1, 0,-1,-1,-1 }, // 12
};
const int n = 10000100;

static void Main()
{
bool[] f = new bool[1001];
Stream r = Console.OpenStandardInput();
byte[] p = new byte[n];
int j, k = 0, l = r.Read(p, 0, n);
for (j = 0; p[j] != 13; j++);
for (int s = 0, i = l - 3; i > j; i--)
{
if (p[i] == 10)
{
f[k++] = s == 0;
i--;
s = 0;
}
else if (s >= 0) s = b[s, a[p[i] - 97]];
}
for (k--; k >= 0; k--)
{
Console.WriteLine(f[k] ? "YES" : "NO");
}
}
}
绿色夹克衫 2009-03-22
  • 打赏
  • 举报
回复
恩,0.203确实是个很不错的成绩,我把判断部分结构调整了一下,提高到了0.25
我想即使再优化几次,也很难达到这个成绩了,不过相信核心的东西应该是差不多的,
wuyi8808 2009-03-22
  • 打赏
  • 举报
回复
C#的最好成绩提高到0.171秒:
2514391 05:56:49 22 Mar 2009 xenium9 1102 C# Accepted 0.171 661 KB
加载更多回复(125)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧