牛客网解题-在线编程-2017网易有道_构造队列
来源:互联网 发布:java业务监控系统 编辑:程序博客网 时间:2024/05/18 18:17
1. 题目
- 题目描述
小明同学把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(); //弹出这时候的队头}
做取出队头的值操作的时候,并不弹出当前队头。
小明同学发现,这段程序恰好按顺序输出了1,2,3,…,n。现在小明想让你构造出原始的队列,你能做到吗?
[注:原题样例第三行5有错,应该为3,以下已修正]
- 输入描述
第一行一个整数T(T ≤ 100)表示数据组数,每组数据输入一个数n(1 ≤ n ≤ 100000),输入的所有n之和不超过200000。
- 输出描述
对于每组数据,输出一行,表示原始的队列。数字之间用一个空格隔开,不要在行末输出多余的空格.
示例
输入:
4
1
2
3
10输出:
1
2 1
2 1 3
8 1 6 2 10 3 7 4 9 5
2. 解题思路
原题目的意思:队列中的元素按照“队首元素弹出并放入队尾 -> 队首元素取值输出 -> 队首元素弹出”的步骤进行得到了1,2,…,n的顺序序列。
现需构造原始队列达到此目的。
解题思路:逆向求解。
题目的操作按照如下步骤进行
- (1)原队列(由满到空)队首元素移到队尾
- (2)取出队首元素
- (3)循环n次,放入新队列(由空到满)队尾得到输出
所以可按照如下步骤得到原队列
- (1)循环取出新队列(由满到空)队尾元素n->n-1->n-2…
- (2)放入原队列(由空到满)队首
- (3)将原队列队尾元素移到队首
元素分布还呈现如下特点
- 第一遍:在1,3,5…位置放入1,2,3…等数
- 第二遍:去掉第一遍放入的数,依然每隔一个位置继续放入一个数
- 重复直至放满整个数组。
3. 代码
#include <stdio.h>#include <stdlib.h>#include <string.h>//原始数组构造函数(类队列)void QueueReconstruct(int n, int *queue, int *newQueue, int *head, int *tail){ int data, temp, i = n; while (n > 0) { data = queue[n - 1]; //放入队列head if (i == n) { newQueue[*tail] = data; } else { newQueue[*head] = data; (*head)++; //tail元素放到head temp = newQueue[*tail]; newQueue[*tail] = newQueue[*head]; newQueue[*head] = temp; } //tail指针变化 if (i == n) { (*head)++; n--; continue; } else { (*head)++; (*tail)++; n--; } } return;}int main(){ int queue1[100000], queue2[300000]; memset(queue2, 0, sizeof(queue2)); int n, T; //输入组数T scanf("%d", &T); while (T--) { //输入每行数n scanf("%d",&n); int i = 0, j = 0; //每行对应的数组 for (; i < n; i++) { queue1[i] = i + 1; } //调用队列重建函数 int head = 0, tail = 0; QueueReconstruct(n, queue1, queue2, &head, &tail); //结果输出 for (j = head - 1; j >= tail; j--) { printf("%d%c",queue2[j],j == tail ? '\n' : ' '); } } return 0;}
运行时间:47ms
占用内存:2804K
4. 总结
变量作为函数参数传递且需要进行修改
像程序中的head和tail变量
因为QueueReconstruct执行完需要使用修改后的head和tail来输出数据,所以设置为指针形式
- C语言中没有引用,所以这里不能使用引用,在C++中可以设置为QueueReconstruct(….,int &head, int &tail)的引用形式
变量的作用域简单总结:C语言中的存储类型有extern,static,auto,register四种类型
全局变量
- 一个在所有函数之外定义的变量
- 作用域:整个源程序
存储位置:全局存储区(静态区)或常量区
[1] 普通全局变量定义在主程序或头文件中可以在所有源程序中使用,定义在某个源程序中需要通过extern来进行声明使用
[2] 通过extern也可在其他源文件中使用
[3] 通过static只可以在本程序中使用
局部变量
- 只在特定函数或过程中可以访问的变量
- 作用域:仅限于函数体内部
存储位置:普通局部变量存储在栈区,static局部变量存储在静态区
[1] static修饰的局部变量,存储位置由栈区变为静态区
- [2] static可以修饰函数和变量,修饰函数其作用域仅限当前源文件
程序中head和tail就是main函数中的局部变量,如果不以指针等形式传入QueueReconstruct函数内,由于在QueueReconstruct函数内的局部变量作用域仅为QueueReconstruct函数本身,则在main函数中head和tail的值没有改变。如int n传入函数后虽然进行n–操作,但QueueReconstruct函数执行完输出仍为原来的取值。
Acknowledgements:
http://m.blog.csdn.net/u010429424/article/details/76947514
2017.08.28
- 牛客网解题-在线编程-2017网易有道_构造队列
- 2017网易有道编程题:构造队列
- 构造队列-网易有道2017年内推编程题
- 网易有道2017内推编程题 构造队列(模拟)
- 网易有道2017内推编程题:构造队列 [python]
- 网易有道笔试编程之队列构造
- 网易有道2017内推编程题-网易[编程题]构造队列
- “构造队列”的两种解法-网易有道17届校招内推在线笔试题
- 网易有道2017内推编程题 队列操作(映射)
- 网易有道编程题:恢复队列
- 2017有道内推编程题——构造队列
- 【牛客网】网易有道2017内推编程题
- 网易有道编程题:恢复队列(C++)
- 2017网易有道校招三道编程题
- 网易有道2017内推编程题
- 网易有道2017内推编程题
- 网易有道2017内推编程题
- 网易有道2017内推编程题
- mysql查询分组显示数据结果之GROUP_CONCAT
- API/SPI可拓展性设计
- Hibernate之Criteria基本语法
- Codeforces Round #429 (Div. 1) D. Destiny(主席树)
- opencv 草稿一
- 牛客网解题-在线编程-2017网易有道_构造队列
- Luogu 2330(kruskal)
- Python文件的创建与追加
- 快速排序法C++
- 反射空间编程
- NSPredicate(谓语)-类方法(2)
- Spring事务异常rollback-only 笔记
- TIMEZONE 本地时间---格林时间
- Qt QChart 图形可视化