目录
L2-041 插松枝
题目
人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上,做成大大小小的松枝。他们的工作流程(并不)是这样的:
- 每人手边有一只小盒子,初始状态为空。
- 每人面前有用不完的松枝干和一个推送器,每次推送一片随机型号的松针片。
- 工人首先捡起一根空的松枝干,从小盒子里摸出最上面的一片松针 —— 如果小盒子是空的,就从推送器上取一片松针。将这片松针插到枝干的最下面。
- 工人在插后面的松针时,需要保证,每一步插到一根非空松枝干上的松针片,不能比前一步插上的松针片大。如果小盒子中最上面的松针满足要求,就取之插好;否则去推送器上取一片。如果推送器上拿到的仍然不满足要求,就把拿到的这片堆放到小盒子里,继续去推送器上取下一片。注意这里假设小盒子里的松针片是按放入的顺序堆叠起来的,工人每次只能取出最上面(即最后放入)的一片。
- 当下列三种情况之一发生时,工人会结束手里的松枝制作,开始做下一个:
(1)小盒子已经满了,但推送器上取到的松针仍然不满足要求。此时将手中的松枝放到成品篮里,推送器上取到的松针压回推送器,开始下一根松枝的制作。
(2)小盒子中最上面的松针不满足要求,但推送器上已经没有松针了。此时将手中的松枝放到成品篮里,开始下一根松枝的制作。
(3)手中的松枝干上已经插满了松针,将之放到成品篮里,开始下一根松枝的制作。
现在给定推送器上顺序传过来的 N 片松针的大小,以及小盒子和松枝的容量,请你编写程序自动列出每根成品松枝的信息。
输入格式:
输入在第一行中给出 3 个正整数:N(≤103),为推送器上松针片的数量;M(≤20)为小盒子能存放的松针片的最大数量;K(≤5)为一根松枝干上能插的松针片的最大数量。
随后一行给出 N 个不超过 100 的正整数,为推送器上顺序推出的松针片的大小。
输出格式:
每支松枝成品的信息占一行,顺序给出自底向上每片松针的大小。数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
8 3 4
20 25 15 18 20 18 8 5
输出样例:
20 15
20 18 18 8
25 5
题解
分析一下:
【注:一定是先看小盒子有没有满足条件的松针,小盒子没有才轮的上传送器】
取:
1、先取小盒子(先取最后放入的)的,满足条件就一直取,反之,
(注:进行下面的2的前提:(同时满足)
(1)就是小盒子中最上面的松针不满足要求或者盒子空了
(2)松枝干还没有插满,没插满才轮的上推送器
)
2、看则推送器:
2.1、 松针满足要求,就取之插好,一直从推送器取,盒子取不了
2.2、 不满足要求(也即是退出),有三个原因,也是退出原因
2.2.1 小盒子已经满了,不满足的松针放盒子放不下了
2.2.2 推送器上已经没有松针了
2.2.3 松枝干上已经插满了松针
退:工人会结束手里的松枝制作,开始做下一个
退1、 小盒子已经满了,但推送器上取到的松针仍然不满足要求 。
退2、 小盒子中最上面的松针不满足要求,但推送器上已经没有松针了。
退3、手中的松枝干上已经插满了松针,将之放到成品篮里,开始下一根松枝的制作。
更多的思路写在代码注释里面的,写的很清楚,大家可以仔细看看
/*
分析一下:
【注:一定是先看小盒子有没有满足条件的松针,小盒子没有才轮的上传送器】
取:
1、先取小盒子(先取最后放入的)的,满足条件就一直取,反之,
(注:进行下面的2的前提:(同时满足)
(1)就是小盒子中最上面的松针不满足要求或者盒子空了
(2)松枝干还没有插满,没插满才轮的上推送器
)
2、看则推送器:
2.1、 松针满足要求,就取之插好,一直从推送器取,盒子取不了
2.2、 不满足要求(也即是退出),有三个原因,也是退出原因
2.2.1 小盒子已经满了,不满足的松针放盒子放不下了
2.2.2 推送器上已经没有松针了
2.2.3 松枝干上已经插满了松针
退:工人会结束手里的松枝制作,开始做下一个
退1、 小盒子已经满了,但推送器上取到的松针仍然不满足要求
退2、 小盒子中最上面的松针不满足要求,但推送器上已经没有松针了。
退3、手中的松枝干上已经插满了松针,将之放到成品篮里,开始下一根松枝的制作。
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N= 5e5 + 24, inf = 1e9 + 7, M = 1e1+24;
stack<int> s; //来存小盒子里面的松针的,这个需要后进先出嘛,先取最后放入的
queue<int> q; // 存推送器传送的松针 ,先来先取
int main()
{
int n, m, k, i, j, t;
cin >> n >> m >> k;
for(i = 0; i < n; i ++)
{
cin >> t;
q.push(t); //松针入传送器
}
//开始把松针插到松枝干上
while(1)
{
vector<int> ve; // 定义松枝干
//1、先取小盒子(先取最后放入的)的,满足条件就一直取
/*
原因:
1.1 s小盒子非空,非空才能取嘛
1.2 松枝干插的松针片要小于一根松枝干上能插的松针片的最大数量
1.3 松枝干没有松枝直接插进去,或者满足“需要保证,每一步插到一根非空松枝干上的松针片,不能比前一步插上的松针片大”
*/
while(!s.empty() && ve.size() < k && (ve.size() == 0 || s.top() <= ve[ve.size()-1]))
{
ve.push_back(s.top()); //插进去
s.pop(); //取下来
}
// 退3:手中的松枝干上已经插满了松针,将之放到成品篮里,开始下一根松枝的制作。
if(ve.size() == k)
{
// 输出
for(i = 0; i < ve.size(); i ++)
{
if(i) cout << " ";
cout << ve[i];
}
cout << endl;
// 开始下一轮,这里可能不太好理解continue
/*
因为这里退出的原因是松枝干满了,可能小盒子非空,
我们始终要 先取小盒子里面的松枝
*/
continue;
}
// 接下来是松枝干还没有装满,开始看推送器的,有没有满足条件的
while(!q.empty() && ve.size() < k)
{
if(ve.size() == 0 || q.front() <= ve[ve.size()-1])
{
ve.push_back(q.front()); //插进去
q.pop(); //取下来
}
// q.front() > ve[ve.size()-1]
else
{
// 小盒子能装下
if(s.size() < m)
{
s.push(q.front()); //插进小盒子
q.pop(); //取下来
}
//. 退1:小盒子已经满了,但推送器上取到的松针仍然不满足要求。
else
{
break;
}
}
}
// 退出整个过程,松针插完了 ,不然ve不可能为空
if(ve.size() == 0) break;
// 下面输出:原因:退1-退3三个原因都可能,就是不满足上面while里面的条件
for(i = 0; i < ve.size(); i ++)
{
if(i) cout << " ";
cout << ve[i];
}
cout << endl;
}
return 0;
}
L2-042 老板的作息表
题目
新浪微博上有人发了某老板的作息时间表,表示其每天 4:30 就起床了。但立刻有眼尖的网友问:这时间表不完整啊,早上九点到下午一点干啥了?
本题就请你编写程序,检查任意一张时间表,找出其中没写出来的时间段。
输入格式:
输入第一行给出一个正整数 N,为作息表上列出的时间段的个数。随后 N 行,每行给出一个时间段,格式为:
hh:mm:ss - hh:mm:ss
其中 hh
、mm
、ss
分别是两位数表示的小时、分钟、秒。第一个时间是开始时间,第二个是结束时间。题目保证所有时间都在一天之内(即从 00:00:00 到 23:59:59);每个区间间隔至少 1 秒;并且任意两个给出的时间区间最多只在一个端点有重合,没有区间重叠的情况。
输出格式:
按照时间顺序列出时间表中没有出现的区间,每个区间占一行,格式与输入相同。题目保证至少存在一个区间需要输出。
输入样例:
8
13:00:00 - 18:00:00
00:00:00 - 01:00:05
08:00:00 - 09:00:00
07:10:59 - 08:00:00
01:00:05 - 04:30:00
06:30:00 - 07:10:58
05:30:00 - 06:30:00
18:00:00 - 19:00:00
输出样例:
04:30:00 - 05:30:00
07:10:58 - 07:10:59
09:00:00 - 13:00:00
19:00:00 - 23:59:59
题解
这道题,我只想发出数学老师的感叹:完全就是送分题!!!知识要注意细节,00:00:00和23:59:59这两个边界值,排下序,看看这个数的开始时间是否是前一个数的结束时间即可,可以用结构体排序、优先队列、vector,我写了两个,思路是差不多的,一个是今年写的,一个是去年备赛的时候写的
// 用结构体排序
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N= 5e5 + 24, inf = 1e9 + 7, M = 1e1+24;
struct point{
string begin;
string end;
}p[N];
bool cmp(point x, point y)
{
// if(x.begin == y.begin) return x.end < y.end;
return x.begin < y.begin;
}
int main()
{
int n, i, j;
string s;
cin >> n;
for(i = 0; i < n; i ++)
{
cin >> p[i].begin >> s >> p[i].end;
}
sort(p, p+n, cmp);
s = "00:00:00";
for(i = 0; i < n; i ++)
{
if(p[i].begin != s) cout << s << " - " << p[i].begin << endl;
s = p[i].end;
}
if(s != "23:59:59") cout << s << " - 23:59:59";
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
const int N = 5e3+5 , M = 1e3+24 ;
vector< pair<string,string> > v ;
pair<string,string> temp ;
int main()
{
int n , i , j ;
string a , b , c , s ;
cin >> n ;
for(i = 0 ; i < n ; i ++)
{
cin >> temp.first >> s >> temp.second ;
v.push_back(temp) ;
}
// for(i = 0 ; i < v.size() ; i ++)
// {
// cout << v[i].first << " " << v[i].second << endl ;
// }
sort(v.begin() , v.end()) ;
// for(i = 0 ; i < v.size() ; i ++)
// {
// cout << v[i].first << " " << v[i].second << endl ;
// }
string last = "-1" ;
for(i = 0 ; i < v.size() ; i ++)
{
temp = v[i] ;
if(last == "-1")
{
if(temp.first != "00:00:00")
{
cout << "00:00:00 - " << temp.first << endl ;
// printf("00:00:00 - %s\n" , temp.fisrt) ;
}
last = temp.second ;
}
else
{
if(last != temp.first)
{
cout << last << " - " << temp.first << endl ;
}
last = temp.second ;
}
}
if(last != "23:59:59") cout << last << " - 23:59:59" ;
return 0 ;
}