HDU3415
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
int a[111111];
int sum[211111];
const int INF = 0x3fffffff;
int main()
{
int t,n,m,i,j,k,head,end;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
j = n;
sum[0] = 0;
for(i = 1; i<=n; i++)
{
scanf("%d",&a[i]);
sum[i] = sum[i-1]+a[i];//将前i项和全部存入sum数组中
}
int ans = -INF;
for(i = n+1; i<n+k;i++)
sum[i] = sum[i-1]+a[i-n];
n = n+k-1;
deque<int> Q;//双向队列
Q.clear();
for(i = 1; i<=n; i++)
{
while(!Q.empty() && sum[i-1]<sum[Q.back()])//保持队列的单调性 至于为什么是i-1 因为队列里面存放的是下标
//什么下标?不是开始的下标,而是真正起始的位置减1。
Q.pop_back();
while(!Q.empty() && Q.front()<i-k)//超过k的长度则消除队列前面的元素
Q.pop_front();
Q.push_back(i-1);
if(sum[i]-sum[Q.front()]>ans)//记录,sum[n]-sum[m]所得出的是n到m+1之间的和
{
ans = sum[i]-sum[Q.front()];
head = Q.front()+1; //队列元素加1才是起始位置!
end = i; //当前位置为终态,所以是i。
}
}
if(end>j)
end%=j;
printf("%d %d %d\n",ans,head,end);
}
return 0;
}
关于lower_bound的用法 点击打开链接
C++ < algorithm > 中定义的reverse函数用于反转在[first,last)范围内的顺序
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first,BidirectionalIterator last);
- 1
- 2
例如,交换vector容器中元素的顺序
vector<int> v={1,2,3,4,5};
reverse(v.begin(),v.end());//v的值为5,4,3,2,1
- 1
- 2
当然,你也可以通过它方便的反转string类的字符串
string str="C++REVERSE";
reverse(str.begin(),str.end());//str结果为ESREVER++C
//大致题意:给定连续的矩形的宽和长,求出最大的连续矩形的面积
/*
维护一个栈中元素高度单调递增的栈,初始化栈中第一个元素高度宽度均为0,
然后每次读入一个矩形,若它比栈顶元素还高就直接进栈,
否则不断将栈中元素弹栈,直到当前栈顶元素能够与读入的矩形满足高度递增。
弹栈过程中累加弹出的元素的宽度,然后每弹出一个就判断当前弹出元素的高度×
累加的宽度能否更新最大面积ans。然后以新的矩形作高,
已经弹出栈的元素总宽度加上新矩形宽度作宽,把这个矩形插入到栈里。
最终栈肯定是一个单调的,只需要再把栈一个个弹空,弹栈过程中仍像上面那样计算即可。
*/
#include <iostream>
#include <cstring>
#include <stack>
using
namespace
std;
typedef
struct
Node
{
int
w,h;
}Node;
int
main()
{
int
i,j,k,T;
stack <Node > s;
while
(cin>>T,~T)
{
int
max_area = 0;
int
total_w,cur_area;
Node *rect =
new
Node[T+2];
for
(i=0;i<T;i++)
{
cin>>rect[i].w>>rect[i].h;
if
(s.empty())
s.push(rect[i]);
else
{
total_w=cur_area=0;
if
(rect[i].h>=s.top().h)
//此处是大于等于
s.push(rect[i]);
else
{
while
(!s.empty())
{
if
(rect[i].h<s.top().h)
//此处只是小于
{
total_w += s.top().w;
if
((cur_area=total_w*s.top().h)>max_area)
max_area = cur_area;
s.pop();
}
else
break
;
//跳出和继续下一次是不一样的
}
total_w += rect[i].w;
rect[i].w = total_w;
s.push(rect[i]);
}
}
}
total_w = cur_area = 0;
while
(!s.empty())
{
total_w += s.top().w;
if
((cur_area=total_w*s.top().h)>max_area)
max_area = cur_area;
s.pop();
}
cout<<max_area<<endl;
delete
[]rect;
//加不加均AC
}
//system("pause");<br> s.clear();//没加也AC
return
0;
}
一.unique函数
类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素。
该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序改变了),表示无重复的值范围得结束。
- #include<stdio.h>
- #include<algorithm>
- using namespace std;
- int main()
- {
- int n;
- int a[11100];
- while(scanf("%d",&n)!=EOF)
- {
- for(int i=0;i<n;i++)
- {
- scanf("%d",&a[i]);
- }
- sort(a,a+n);
- int ans=unique(a,a+n)-a;
- printf("*******%d*******\n",ans);
- }
- return 0;
- }
运行结果:
● 如果你需要在vector、string、deque或数组上进行完全排序,你可以使用sort或stable_sort。 ● 如果你有一个vector、string、deque或数组,你只需要排序前n个元素,应该用partial_sort。 ● 如果你有一个vector、string、deque或数组,你需要鉴别出第n个元素或你需要鉴别出最前的n个元素,而不用知道它们的顺序,nth_element是你应该注意和调用的。 ● 如果你需要把标准序列容器的元素或数组分隔为满足和不满足某个标准,你大概就要找partition或stable_partition。