WEEK5程序作业

A - 最大矩形

Input

Output

Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Sample Output
8
4000

#include<iostream>
#include<stdio.h>
#include<queue>
#include<stack>
using namespace std;
struct array0 {
int ii;//记录下标
int left;
int right;
int value;
long long s;
};
array0 a[100000];
int main()
{
stack<int> st;
stack<int> st1;

int n;
int i;
while (1)
{
//		scanf("%d", &n);
cin >> n;
if (n == 0)
{
break;
}
for (i = 0;i < n;i++)
{
//	scanf("%d", &a[i].value);
cin >> a[i].value;
a[i].ii = i;
//st只保存数组的下标
while (!st.empty() && a[st.top()].value >= a[i].value)
{
//	cout << "下标为" << st.top() << "的元素会被弹出" << endl;
st.pop();

}

if (st.empty())
{
a[i].left = -1;
}
else
{
a[i].left = st.top();
//	cout << "st.top().ii= " << st.top().ii << endl;
}
st.push(a[i].ii);
//cout << "a[" << i << "].value ="<<a[i].value<< "		a[" << i << "].left = " << a[i].left << endl;
}
/////////////////////////////////////////////
for (int j = n - 1;j >= 0;j--)
{
while (!st1.empty() && a[st1.top()].value >= a[j].value)
{
//	cout << "st1.[" << st1.top() << "] 被弹出" << endl;
st1.pop();
}
if (st1.empty())
{
a[j].right = n;
}
else
{

a[j].right = st1.top();
}
st1.push(a[j].ii);
a[j].s = (long long)((long long)a[j].value *((long long)(a[j].right - a[j].left - 1)));

//		cout << "a[" << j << "].right = " << a[j].right << endl;
//	cout << "a[" << j << "].s = " << a[j].s << endl;
}
///////////////////////////////////////////////////

long long max = 0;
for (int j = 0;j < i;j++)
{
if (a[j].s >= max)
{
max = a[j].s;
}
}
cout << max << endl;
while (!st.empty())
{
st.pop();
}
while (!st1.empty())
{
st1.pop();
}
}

return 0;
}


B - TT’s Magic Cat

Thanks to everyone’s help last week, TT finally got a cute cat. But what TT didn’t expect is that this is a magic cat.

One day, the magic cat decided to investigate TT’s ability by giving a problem to him. That is select n cities from the world map, and a[i] represents the asset value owned by the i-th city.

Then the magic cat will perform several operations. Each turn is to choose the city in the interval [l,r] and increase their asset value by c. And finally, it is required to give the asset value of each city after q operations.

Could you help TT find the answer?

Input
The first line contains two integers n,q (1≤n,q≤2⋅105) — the number of cities and operations.

The second line contains elements of the sequence a: integer numbers a1,a2,…,an (−106≤ai≤106).

Then q lines follow, each line represents an operation. The i-th line contains three integers l,r and c (1≤l≤r≤n,−105≤c≤105) for the i-th operation.

Output
Print n integers a1,a2,…,an one per line, and ai should be equal to the final asset value of the i-th city.

Examples
Input
4 2
-3 6 8 4
4 4 -2
3 3 1
Output
-3 6 9 2
Input
2 1
5 -2
1 2 4
Output
9 2
Input
1 2
0
1 1 -8
1 1 -6
Output
-14

#include<iostream>
#include<stdio.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<math.h>
using namespace std;
long long a[300001];
long long b[300001];
int main()
{
for (int i = 0;i < 300001;i++)
{
b[i] = 0;
}
int n, q;
cin >> n >> q;//n代表了元素的个数。q代表操作的个数
for (int i = 1;i <= n;i++)
{
cin >> a[i];
if (i != 1)
{
b[i] = a[i] - a[i - 1];
}
else
{
b[i] = a[i];
}
}
for (int i = 0;i < q;i++)
{
int l, r;
long long c;
cin >> l >> r >> c;
b[l] = b[l] + c;
b[r + 1] = b[r + 1] - c;
}
long long sum = 0;
for (int i = 1;i <= n;i++)
{
sum += b[i];
cout << sum << " ";

}

return 0;
}


C - 平衡字符串

Input

Output

Examples
Input
QWER
Output
0
Input
QQWE
Output
1
Input
QQQW
Output
2
Input
QQQQ
Output
3
Note
1<=n<=10^5

n是4的倍数

#include<cmath>
#include<map>
#include <algorithm>
#include<iostream>
#include<string>
using namespace std;
string st;  //用来装字母
int  begin0, end0;
map<char, int> mp;
int main()
{
begin0 = end0 = 0;
cin >> st;
int len = st.size();
for (int i = 0; i < 4;i++)
{
mp[i] = 0;
}
for (int i = 0; i < len ;i++)
{
mp[st[i]]++;
}
int n = len / 4;
if (mp[0] == n && mp[1] == n && mp[2] == n && mp[3] == n)
{
cout << 0 << endl;
return 0;
}

int result = len;
//int mm = 0;
while (end0 < len)
{
//	cout << "mp['Q']=" << mp['Q'] << "mp['W']=" << mp['W'] << "mp['E']=" << mp['E'] << "mp['R']=" << mp['R'] << endl;
mp[st[end0]]--;  //右移
bool key = 1;
if (mp['Q'] > n || mp['W'] > n || mp['E'] > n || mp['R'] > n)
{
key = 0;
}
while (key == 1 && begin0 < len)
{
//result记录当前符合要求的最短区间
result = min(result, end0 - begin0 + 1);
mp[st[begin0]]++;    //左边界右移
//	cout << "result = " << result << endl;
if (mp[st[begin0]] > n)    //mp[i]中仅有st[begin0]变化
{
key = 0;
}
begin0++;

}
end0++;	//移右框
}
cout << result << endl;
return 0;
}


D - 滑动窗口（C++和G++都交一下）

ZJM 有一个长度为 n 的数列和一个大小为 k 的窗口, 窗口可以在数列上来回移动. 现在 ZJM 想知道在窗口从左往右滑的时候，每次窗口内数的最大值和最小值分别是多少. 例如：

Window position Minimum value Maximum value
[1 3 -1] -3 5 3 6 7 -1 3
1 [3 -1 -3] 5 3 6 7 -3 3
1 3 [-1 -3 5] 3 6 7 -3 5
1 3 -1 [-3 5 3] 6 7 -3 5
1 3 -1 -3 [5 3 6] 7 3 6
1 3 -1 -3 5 [3 6 7] 3 7
Input

Output

Sample Input
8 3
1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7

#include <iostream>
#include<stdio.h>
using namespace std;
const int N = 1000008;
int min_[N], max_[N], index[N], a[N];
int n, k;
void Max()
{
int left = 1, right = 0;
for (int i = 1; i <= n; i++)
{
while (right >= left && a[index[right]] <= a[i]) right--;//维护单调递增队列
right++;//新队列元素总是安排在队尾
index[right] = i;//记录当前队列中对应元素的下标
if (index[right] - index[left] + 1 > k)	left++;//去除原队首元素，进入新的队列
//i的有效位仅从k+1起
max_[i] = a[index[left]];
}
}
void Min()
{
int left = 1, right = 0;
for (int i = 1; i <= n; i++)
{
while (right >= left && a[index[right]] >= a[i]) right--;
index[++right] = i;
if (index[right] - index[left] + 1 > k)	left++;
min_[i] = a[index[left]];
}
}
int main()
{
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
Min();
Max();
for (int i = k; i <= n; i++) printf("%d ", min_[i]);
cout << endl;
for (int i = k; i <= n; i++) printf("%d ", max_[i]);

return 0;
}

cout << result << endl;
return 0;
}


©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试