一道测试题,我自己感觉代码没问题,但是一直是运行超时。

firerun 2018-01-09 11:18:54

#include <iostream>

#define cin std::cin
#define cout std::cout
#define endl std::endl

typedef unsigned short ushort;
typedef unsigned int uint;

typedef struct _Process
{
ushort time;
ushort piece;
ushort memory;
_Process *next;

_Process(ushort t, ushort m, ushort p, _Process *n = NULL)
: time(t), piece(p), memory(m), next(n)
{}
} Process;

typedef struct _Ing
{
ushort addr;
ushort time;
_Process *process;
_Ing *next;

_Ing(ushort a, ushort t, _Process *p, _Ing *n = NULL)
: addr(a), time(t), process(p), next(n)
{}
} Ing;

uint memorysize = 0;
uint count = 0;
Process *list = NULL;
Process *waits = NULL;
Ing *ings = NULL;

template <typename T>
void append(T **list, T *node)
{
node->next = NULL;
T *iter = *list;
while (iter)
iter = iter->next;

if (iter)
iter->next = node;
else
*list = node;
}

bool process0(Process *p, uint clock)
{
bool r = false;
Ing *iter = ings;
uint nextaddr = iter ? iter->addr : memorysize;

if (p->memory <= nextaddr)
{
Ing *ing = new Ing(0, clock, p, iter);
ings = ing;
r = true;

// cout << "@@@" << p->time << " @ " << ing->addr << endl;
}

return r;
}

bool processn(Process *p, uint clock)
{
Ing *itercurr = ings;
Ing *iternext;
uint nextaddr;
bool r = 0;

while (itercurr)
{
iternext = itercurr->next;
nextaddr = iternext ? iternext->addr : memorysize;

if (itercurr->addr + itercurr->process->memory + p->memory <= nextaddr)
{
Ing *ing = new Ing(itercurr->addr + itercurr->process->memory, clock, p, iternext);
itercurr->next = ing;
r = true;

// cout << "@@@" << p->time << " @ " << ing->addr << endl;

break;
}

itercurr = iternext;
}

return r;
}

bool process(Process *p, uint clock)
{
bool r = false;

r = process0(p, clock);

if (!r)
r = processn(p, clock);

return r;
}

void timeout(uint clock)
{
Ing *itercurr = ings;
Ing *iterprev = NULL;

while (itercurr)
{
if (itercurr->time + itercurr->process->piece - 1 <= clock)
{
// cout << "***" << clock << ' ' << itercurr->process->time << " delete" << endl;

if (iterprev)
iterprev->next = itercurr->next;

if (itercurr == ings)
ings = itercurr->next;

delete itercurr->process;
delete itercurr;

itercurr = iterprev ? iterprev->next : ings;

continue;
}

iterprev = itercurr;
itercurr = itercurr->next;
}
}

uint run()
{
uint clock;

while (waits || list || ings)
{
if (clock == -1)
break;

// cout << "xxxxxxxxxxxxxxxxxxxx " << clock << endl;

if (waits && waits->time < clock)
{
// cout << "..." << clock << ' ' << waits->time << endl;
if (process(waits, clock))
{
waits = waits->next;
continue;
}
}

if (list && list->time == clock)
{
// cout << "===" << clock << ' ' << list->time << endl;
Process *next = list->next;

if (!process(list, clock))
{
append(&waits, list);
count++;
}

list = next;

if (list && list->time == clock)
continue;
}

timeout(clock);
clock++;
}

return clock;
}

bool newline()
{
char chr;
while (chr = cin.get())
{
if (chr == '\n')
break;

if (chr != ' ')
{
cin.unget();
break;
}
}

return chr == '\n';
}

int main(int argc, char *argv[])
{
Process *iter = list;

int time;
int memory;
int piece;

for (int i = 0; i < 10000; i++)
{
if (i > 0)
{
cin >> time;
if (newline())
continue;

cin >> memory;
if (newline())
continue;

cin >> piece;
cin.ignore(1024, '\n');

if (time == 0 && memory == 0 && piece == 0)
break;

if (time >= 109 || memory >= 109 || piece >= 109)
continue;

if (memory > memorysize)
continue;

Process *p = new Process(time, memory, piece);

if (list == NULL)
list = p;
else
iter->next = p;

iter = p;

continue;
}

cin >> memorysize;
cin.ignore(1024, '\n');
}

time = run();
cout << time << endl;
cout << count << endl;

return 0;
}

先是对题目的疑问:
1 输入文件一共10000行,那包括第一行吗?是不是那个循环应该是 < 9999
2 我到底用不用排序,因为题目说数据已经按照T从小到大排序,所以我就没做排序处理。

接着是对代码的一点问题:
1 没有用std的list、queue,是因为想让程序运行时内存相对小点。
2 运行超时Time Limit Exceeded,是程序逻辑结构有问题吗?是哪里进入了死循环吗?

我自己测试反正是运行良好的。
...全文
685 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-01-09
  • 打赏
  • 举报
回复
边界条件 输入输出格式 ……
firerun 2018-01-09
  • 打赏
  • 举报
回复
但是可能是测试数据的局限,我并没有碰到wrong answer
firerun 2018-01-09
  • 打赏
  • 举报
回复
我把clock初始化为0了,现在出现了wrong answer。
firerun 2018-01-09
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
run函数中if (clock == -1)第一次执行时,clock的值没有初始化就使用了
谢谢,是一个问题。
paschen 版主 2018-01-09
  • 打赏
  • 举报
回复
run函数中if (clock == -1)第一次执行时,clock的值没有初始化就使用了
firerun 2018-01-09
  • 打赏
  • 举报
回复
这里需要改动,改完了还是 wrong answer
template <typename T>
void append(T **list, T *node)
{
    node->next = NULL;
    T *iter = *list;

    while (iter && iter->next)
        iter = iter->next;

    if (iter)
        iter->next = node;
    else
        *list = node;
}
  • 打赏
  • 举报
回复
开始的超时没有判定错,后面的报错(非编译错误)应该也是没有判定错的。 代码规范我就不说了,改了一下main内容,不过可能还需要你自己调一下。 为什么会出错,我已经写到注释里了,自己看看吧。
int main(int argc, char *argv[])
{
    Process *iter = list;
 
    int time;
    int memory;
    int piece;

    //读取内存最大值,因为就一行,没必要那么麻烦的去在for循环里判断,
    //原来的那个for循环是个线性增加的,而且还不算你在里面调用函数的时间,
    //判断消耗的时间,等等,学过算法吧?线性时间意味这什么应该是懂的吧?
    //本身main函数的for循环就是线性时间的了,再加上如果其他函数没写好
    //超时错误不就很正常了?
    int N;
    cin >> N;
    
    //当有读数的时候
    while (cin >> time >> memory >> piece)
    {
        //读取到文件结尾,结束
        if (time == 0)
          if (memory == 0) 
            if (piece == 0) break;

        //抛弃字符
        cin.ignore(1024, '\n');
        
            //不知道你这一段要干啥,我就直接注释掉了,自己看情况需不需要使用
            // if (time == 0 && memory == 0 && piece == 0)
            //     break;
            // 
            // if (time >= 109 || memory >= 109 || piece >= 109)
            //     continue;
            // 
            // if (memory > memorysize)
            //     continue;

            //之后的内容,基本没变
            Process *p = new Process(time, memory, piece);

            //你这是要干啥?else后面那三条貌似应该属于else子句吧?没用大括号包起来?
            // if (list == NULL)
            //     list = p;
            // else
            //     iter->next = p;
            // 
            // iter = p;
            // 
            // continue;
        }

        //这个地方是将KB转换成MB,GB?我也留下了。
        cin >> memorysize;
        cin.ignore(1024, '\n');
    }
 
    time = run();
    cout << time << endl;
    cout << count << endl;
 
    return 0;
}
firerun 2018-01-09
  • 打赏
  • 举报
回复
是不是我多输出了一个空行啊?

64,678

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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