标签:
有道笔试过了两天了,我其实当时就想着写篇文章好好反省下。这个编程题一道题都没AC,如果我要归咎责任,掩人耳目,保留面子,那么我会说第一道题把我卡住了,而且第一题的样例有误。但是诚实地说,是我的编程方法不对。
编程,你一定要知道解决问题的算法,知道了算法之后实现是第二步。所以假若没有想到算法就编程,那么就不可能顺利AC。而编程的规则,大部分是从题目翻译。这点考验理解力和算法基础。规则,你或者说算法很重要。有了算法之后实现就容易多了。而我在有道笔试的时候,自己主观想象的算法当总数为4时,没问题。是10就完全不对。原因很简单,没去理解问题,直接以最简单的样例来拼凑规则,这样拼凑出来的算法就很多不一定了。确实,样例的最后一个一直过不了。也好在我静下心来,只为自己的一道编程题AC而努力。最后,算法算是正确,但由于时间不够了,边界条件并未处理好。下面是题目:
小明同学把1到n这n个数字按照一定的顺序放入了一个队列Q中。现在他对队列Q执行了如下程序:
while(!Q.empty()) //队列不空,执行循环
{
int x=Q.front(); //取出当前队头的值x
Q.pop(); //弹出当前队头
Q.push(x); //把x放入队尾
x = Q.front(); //取出这时候队头的值
printf("%d\n",x); //输出x
Q.pop(); //弹出这时候的队头
}我的代码如下:
#include<queue>
#include<stack>
#include<vector>
#include<iostream>
using namespace std;
void PrintOrigin(int n)
{
queue<int>ret;
queue<int>a;
int p=n;
ret.push(n);
while(p>0)
{
p--;
if(p>0)a.push(p);
a.push(ret.back());
while(ret.size()>1)
{
int k=ret.front();
ret.pop();
a.push(k);
}
ret.pop();
if(p==0)break;
while(!a.empty())
{
int k=a.front();
a.pop();
ret.push(k);
}
}
while(!a.empty())
{
int k=a.front();
a.pop();
printf("%d ",k);
}
}
int main()
{
int N;
while(cin>>N)
{
while(N--)
{
int n;
cin>>n;
PrintOrigin(n);
printf("\n");
}
}
return 0;
}
这个代码提交之后,未能在规定时间内完成任务。也是我用了两个队列不停地push和pop,这样很浪费操作时间。果然,再看算法,好像只用一个动态增长的数组,只用增加元素,挪动元素即可。这样,就有了如下代码:
#include<queue>
#include<stack>
#include<vector>
#include<iostream>
using namespace std;
void PrintOrigin(int n)
{
vector<int>ret;
ret.push_back(n);
int tmp=n;
int i=0;
if(n==1)
{
printf("1");
return;
}
tmp--;
ret.push_back(tmp);
tmp--;
i++;
if(n==2)
{
printf("2 1");
return;
}
while(tmp>=0)
{
if(tmp>0)ret.push_back(tmp);
i++;
int k=ret[0];
int p=i-1;
int begin=0;
while(begin<p)
{
ret[begin]=ret[begin+1];
begin++;
}
ret[i-1]=k;
tmp--;
}
int nr=ret.size();
for(int i=nr-1;i>=0;i--)
if(i==0)printf("%d",ret[i]);
else printf("%d ",ret[i]);
}
int main()
{
int N;
while(cin>>N)
{
while(N--)
{
int n;
cin>>n;
PrintOrigin(n);
printf("\n");
}
}
return 0;
}写这篇文章的目的,一是提醒自己编程时必须已经有解法,如果没有,要继续去寻求规则。二是要注意编程的一些技巧,如边界条件和优化等。
标签:
原文地址:http://blog.csdn.net/yutianxin123/article/details/52252017