目录
A - AtCoder Line
题意:
有n站列车,列车从x站开往y站,需要在z站上车。如果能,输出Yes,反之,输出No。
代码:
//AtCoder Beginner Contest 352
//A - AtCoder Line
//https://atcoder.jp/contests/abc352/tasks/abc352_a
//Time Limit: 2 sec
//Memory Limit: 1024 MB
//
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int n,x,y,z;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>x>>y>>z;
if(x>y)
swap(x,y);
if(x<z&&y>z)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
return 0;
}
B - Typing
题意:
有字符串 s 和字符串 t ,在 t 中找到字符串 s 中字符的位置,并输出。
注意:下标从1开始。
代码:
//AtCoder Beginner Contest 352
//B - Typing
//https://atcoder.jp/contests/abc352/tasks/abc352_b
//Time Limit: 2 sec
//Memory Limit: 1024 MB
//
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+5;
string s,t;
int pos[N];
int p=0;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>s>>t;
int lens=s.length();
int lent=t.length();
int j=0;
for(int i=0;i<lens;i++){
while(t[j++]!=s[i])
;
pos[p++]=j;
}
for(int i=0;i<p;i++){
cout<<pos[i];
if(i!=p-1)
cout<<" ";
}
return 0;
}
C - Standing On The Shoulders
题意:
有n个巨人,堆叠在一起。堆叠的规则是:从地面开始,除了第一个巨人脚踩地面,其余巨人踩着下面巨人的肩膀。求最后一个巨人,头顶距离地面的距离最大值。
思路:
将n个巨人的头长度进行从小到大排序,每个巨人之间踩着肩膀,所以身高在相加的时候无需考虑,只需要找到最大头的那个巨人即可。答案就是:sum=所有巨人的高度肩高+最大头的头的高。
代码:
//AtCoder Beginner Contest 352
//C - Standing On The Shoulders
//https://atcoder.jp/contests/abc352/tasks/abc352_c
//Time Limit: 2 sec
//Memory Limit: 1024 MB
//
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
typedef struct Giant{
int shoulder;
int height;
int cha;
}Giant;
const int N=2e5+5;
int n;
ll sum=0;
Giant giant[N];
bool cmp(Giant a,Giant b){
if(a.cha<b.cha)
return true;
return false;
}
void Cin(){
cin>>n;
for(int i=0;i<n;i++)
cin>>giant[i].shoulder>>giant[i].height;
}
void Init(){
for(int i=0;i<n;i++){
giant[i].cha=giant[i].height-giant[i].shoulder;
}
}
void Sort(){
sort(giant,giant+n,cmp);
}
void Solve(){
for(int i=0;i<n;i++){
sum+=giant[i].shoulder;
}
sum+=giant[n-1].cha;
cout<<sum<<endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
Cin();
Init();
Sort();
Solve();
return 0;
}
D - Permutation Subsequence
题意:
给定一个数组,数组的下标从1开始,这些数通过排列,可以变成公差为1的等差数列,求排序之后,在区间大小为k的范围内,找到最大的下标和最小的下标之差。
思路:
将数组进行排序后,找个有多少个等差数列,题目要求区间大小为k,则使用滑动窗口来求解。滑动窗口求解最大值和最小值。
代码:
//AtCoder Beginner Contest 352
//D - Permutation Subsequence
//https://atcoder.jp/contests/abc352/tasks/abc352_d
//Time Limit: 2 sec
//Memory Limit: 1024 MB
//
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,k,cc;
int answer[N];//存储 每个队列的最小答案
bool cmp(pair<int ,int >a,pair<int , int >b){
if(a.first<b.first)
return true;
return false;
}
void Mypopmax(deque<int> &que,int value){
if(!que.empty() &&value == que.front()){ //当队首元素等于要上个区间的头部时 删除
que.pop_front();
}
}
void Mypushmax(deque<int> &que,int value){ //
while(!que.empty() && value > que.back()){ //循环:如果当前元素大于队尾,则队尾元素失效了
que.pop_back();
}
que.push_back(value);
}
void Mypopmin(deque<int> &que,int value){
if(!que.empty() &&value == que.front()){
que.pop_front();
}
}
void Mypushmin(deque<int> &que,int value){
while(!que.empty() && value < que.back() ){
que.pop_back();
}
que.push_back(value);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>k;
vector< pair<int ,int > >start_vec;// start_vec记录原始输入的数据。
for(int i=1;i<=n;i++){
int x;
cin>>x;
start_vec.push_back({x,i});
}
sort(start_vec.begin(),start_vec.end(),cmp); //将start_vec以自定义cmp的方式进行排序。
//即按照 点的第一值进行快速排序。
/*for(int i=0;i<n;i++){
cout<<vec[i].first<<" "<<vec[i].second<<endl;
}*/
vector<pair<int ,int > >ans; // ans 用来临时储存公差为1的等差数列
vector< vector< pair<int ,int> > >vs; // vs 来储存 公差为1的等差数列。
ans.push_back(start_vec[0]);// 将第一个元素添加到ans里面。
int nums=0,j=0; // nums统计有多少组公差为1的等差数列。 j是ans储存时的下标。
for(int i=1;i<n;i++){
if(start_vec[i].first-ans[j].first==1){ //满足公差为1
ans.push_back(start_vec[i]); // 将 start_vec[i] 添加到 ans去。
j++; // start_vec[i] 的位置即为 j++。用于与下一个数据进行判断等差数列。
}
else{ //不满足公差为1
vs.push_back(ans); //将ans添加到 vs里去。
nums++; // 数列 数加1。
ans.clear();//清空ans
ans.push_back(start_vec[i]);// 将当前元素作为下一个数列的首项
j=0;//队首下标从0开始
}
}
vs.push_back(ans);// 扫尾
nums++;// 数列 数加1。
for(int ii=0;ii<nums;ii++){ //遍历 vs
vector< pair<int ,int > >vec=vs[ii]; //vec 表示当前队列。
int vec_size=vec.size();// vec_size 表示 队列的长度。
if(vec_size<k)// 如果队列长度<滑动窗口长度,直接跳到下一个队列。
continue;
deque<int>que;
vector<int>maxresult;
int maxx=vec[0].second;
que.push_back(maxx);
for (int i = 1;i < k; i++) { // 先将前k的元素放进队列
maxx=maxx<vec[i].second?vec[i].second:maxx;
while(!que.empty()&&que.front()<vec[i].second){ //如果当前元素大于队首,则队首元素失效了
que.pop_front(); //弹出队首元素。
}
while(!que.empty()&&que.back()<vec[i].second){ //如果当前元素大于队尾,则队尾元素失效了
que.pop_back(); //弹出队尾部元素。
}
que.push_back(vec[i].second); //当前元素进队。
//que.push_back(vec[i].second);
}
maxresult.push_back(maxx); // maxresult 记录前k的元素的最大值
for (int i = k; i < vec_size; i++) {
Mypopmax(que,vec[i-k].second);; // 滑动窗口移除最前面元素
Mypushmax(que,vec[i].second);// 滑动窗口前加入最后面的元素
maxresult.push_back(que.front()); // 记录对应的最大值
/*cout<<que.front()<<" ";*/
}
deque<int>qu;
vector<int>minresult;
int minn=vec[0].second;
qu.push_back(minn);
for (int i = 1;i < k; i++) { // 先将前k的元素放进队列
minn=minn>vec[i].second?vec[i].second:minn;
while(!qu.empty()&&qu.front()>vec[i].second){ //如果当前元素小于队首,则队首元素失效了
qu.pop_front(); //弹出队首元素
}
while(!qu.empty()&&qu.back()>vec[i].second){ //如果当前元素小于队尾,则队尾元素失效了
qu.pop_back(); //弹出队尾元素
}
qu.push_back(vec[i].second);
}
minresult.push_back(minn); // minresult 记录前k的元素的最小值
for (int i = k; i < vec_size; i++) {
Mypopmin(qu,vec[i-k].second);; // 滑动窗口移除最前面元素
Mypushmin(qu,vec[i].second);// 滑动窗口前加入最后面的元素
minresult.push_back(qu.front()); // 记录对应的最小值
/*cout<<qu.front()<<" ";*/
}
//cout<<endl;
int sizee=minresult.size(); //记录滑动窗口的个数
/*cout<<"maxresult"<<endl;
for(int i=0;i<sizee;i++){
cout<<maxresult[i]<<endl;
}
cout<<"minresult"<<endl;
for(int i=0;i<sizee;i++){
cout<<minresult[i]<<endl;
}*/
vector<int>result; //保存对于同一滑动窗口,最大值与最小值之差的结果。
for(int i=0;i<sizee;i++){
result.push_back(maxresult[i]-minresult[i]);
}
sort(result.begin(),result.end());
answer[cc++]=result[0];// 存储每个队列的答案 并记录数量cc++。
}
sort(answer,answer+cc);// 对answer答案进行从小到大快速排序
cout<<answer[0]<<endl;// answer[0]即为结果,输出。
return 0;
}