queue queen(误)

1. POJ2259:据说很容易的队列题(事实好像也是emmm,抛开流氓一样无赖的输入输出格式),把element变index,team number变value比其正常相反的套路要好得多。

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long ll;
15 #define MS(x) memset(x,0,sizeof(x));
16 #define inf 0x3f3f3f3f
17 
18 const int maxn = 1e6 + 10;
19 
20 int team[maxn];
21 
22 int main()
23 {
24     int t;
25     int count = 1;
26     while (scanf("%d", &t) && t != 0)
27     {
28         queue<int> q;
29         queue<int> tq[1005];
30         MS(team);
31         printf("Scenario #%d\n", count);
32         count++;
33         for (int i = 1; i <= t; i++)
34         {
35             int times;
36             scanf("%d", &times);
37             for (int j = 1; j <= times; j++)
38             {
39                 int element;
40                 scanf("%d", &element);
41                 team[element] = i;
42             }
43         }
44         char implement[200];
45         while (scanf("%s", implement) != EOF)
46         {
47             if (implement[0] == 'S')
48                 break;
49             else if (implement[0] == 'E')
50             {
51                 int numb;
52                 scanf("%d", &numb);
53                 if (tq[team[numb]].empty())
54                     q.push(team[numb]);
55                 tq[team[numb]].push(numb);
56             }
57             else if (implement[0] == 'D')
58             {
59                 if (!tq[q.front()].empty())
60                 {
61                     printf("%d\n", tq[q.front()].front());
62                     tq[q.front()].pop();
63                 }
64                 else
65                 {
66                     q.pop();
67                     if (!tq[q.front()].empty())
68                     {
69                         printf("%d\n", tq[q.front()].front());
70                         tq[q.front()].pop();
71                     }
72                 }
73             }
74         }
75         printf("\n");
76     }
77     return 0;
78 }
My queen

 

2. 洛谷P2827这道题是2016NOIP的题(看到一个初三学生的压力准大二阿萌感到。。。罢了罢了)

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long ll;
15 #define MS(x) memset(x,0,sizeof(x))
16 #define inf 0x3f3f3f3f
17 const int maxn = 1e5 + 10;
18 
19 priority_queue<int> rowinsect;//我就说蚯蚓是昆虫咋地啦
20 queue<int> insect1;
21 queue<int> insect2;
22 
23 int main()
24 {
25     int n, m, q, u, v, t;
26     scanf("%d %d %d %d %d %d", &n, &m, &q, &u, &v, &t);
27     double p = (double)u / v;
28     int lenth;
29     for (int i = 1; i <= n; i++)
30     {
31         scanf("%d", &lenth);
32         rowinsect.push(lenth);
33     }
34     int deta = 0;
35     for (int j = 1; j <= m; j++)
36     {
37         int lh, rh, mark0 = -0x7fffffff, mark1 = -0x7fffffff, mark2 = -0x7fffffff;
38         int longest = -0x7fffffff;
39         if (!rowinsect.empty())
40             longest = max(longest, rowinsect.top()), mark0 = rowinsect.top();
41         if (!insect1.empty())
42             longest = max(longest, insect1.front()), mark1 = insect1.front();
43         if (!insect2.empty())
44             longest = max(longest, insect2.front()), mark2 = insect2.front();
45         if (longest == mark0)
46             rowinsect.pop();
47         else if (longest == mark1)
48             insect1.pop();
49         else
50             insect2.pop();
51         longest += deta;
52         int pl = p * longest;
53         lh = pl - q - deta;
54         rh = longest - pl - q - deta;
55         deta += q;
56         if (j >= t && j % t == 0)
57             printf("%d ", longest);
58         insect1.push(lh);
59         insect2.push(rh);
60     }
61     printf("\n");
62     for (int i = 1; !rowinsect.empty() || !insect1.empty() || !insect2.empty(); i++)
63     {
64         int mark0 = -0x7fffffff, mark1 = -0x7fffffff, mark2 = -0x7fffffff;
65         int longest = -0x7fffffff;
66         if (!rowinsect.empty())
67             longest = max(longest, rowinsect.top()), mark0 = rowinsect.top();
68         if (!insect1.empty())
69             longest = max(longest, insect1.front()), mark1 = insect1.front();
70         if (!insect2.empty())
71             longest = max(longest, insect2.front()), mark2 = insect2.front();
72         if (i >= t && i % t == 0)
73             printf("%d ", longest + deta);
74         if (longest == mark0)
75             rowinsect.pop();
76         else if (longest == mark1)
77             insect1.pop();
78         else
79             insect2.pop();
80     }
81     return 0;
82 }
My queen

 

这里有两个点,第一个每切一次是需要将所有元素+q,用遍历太TLE了所以我们就用了一个deta来储存q值得累积度,和我想的一样就是其他不变单独减那两条被剪的,在后面再加回来。第二点就是如果单独用一个优先队列,那么由于二叉堆的劣根性我们还是会在某些数据上TLE,所以题解是推荐再用两个数组/普通队列进行维护,理论基础(不需要优先队列自动排序的理由)是每次先剪的蚯蚓分成的两半一定比后减的两半各比例分别都要长,所以把这两个比例用两个数组/队列存起来,得到的数组/队列本身就具备了单调性,所以一次弹出将三个top()比较也不会有问题啦。

(洛谷还有其他解法到时看心情(我觉得以后有缘吧)看咯)

3. BZOJ 2457:双端队列,(但事实不需要用队列,只是解题需要通晓队列的知识从而得出规律)(最后还是顺着点拨用自己的思路杠出来了——所以和网上标准题解不同滴!)

 

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long ll;
15 #define MS(x) memset(x,0,sizeof(x))
16 #define inf 0x3f3f3f3f
17 const int maxn = 2e5 + 10;
18 
19 pair<int, int> vi[maxn];//value and index
20 int mx[maxn];
21 int mi[maxn];
22 
23 bool cmp(pair<int, int>v1, pair<int, int>v2)
24 {
25     return v1.first == v2.first ? (v1.second < v2.second) : (v1.first < v2.first);
26 }
27 
28 int main()
29 {
30     int N;
31     scanf("%d", &N);
32     for (int i = 1; i <= N; i++)
33         scanf("%d", &vi[i].first), vi[i].second = i;
34     sort(vi + 1, vi + N + 1, cmp);//由此得到关于index的变化曲线,根据规律(什么规律?自己找去)得出极小值的个数就是双端队列的个数
35     int cnt = 0;
36     for (int i = 1; i <= N; i++)
37     {
38         if (i == 1 || vi[i].first != vi[i - 1].first)
39         {
40             mx[cnt] = vi[i - 1].second;//mx表示相同value时index最大的那一个
41             mi[++cnt] = vi[i].second;//mi表示value相同时index最小的那一个
42         }
43     }
44     mx[cnt] = vi[N].second;
45     int ans = 1;
46     bool decrease = true;//判断当前为递增/递减(初始为递减)
47     int now = 0x7f7f7f7f;//当前值
48     for (int i = 1; i <= cnt; i++)//tips:i<cnt
49     {
50         if (decrease)
51         {
52             if (now > mx[i])
53                 now = mi[i];
54             else
55                 now = mx[i], decrease = false;
56         }
57         else
58         {
59             if (now > mi[i])
60                 now = mi[i], decrease = true, ans++;//以再一次递减为标志ans+1
61             else
62                 now = mx[i];
63         }
64     }
65     printf("%d", ans);
66     return 0;
67 }
My queen

 

 

4.

 

转载于:https://www.cnblogs.com/xzmxiao/p/11409372.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值