AtCoder Beginner Contest 247
A - Move Right
题意
给出一个01字符串,整体往右一位,多余的舍去,空出来的补0
思路
模拟,还有啥好说的
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
typedef long long ll;
char ch[N];
int main(){
cin>>(ch);
cout<<"0";
for(int i = 0;i<strlen(ch)-1;i++){
cout<<ch[i];
}
return 0;
}
B - Unique Nicknames
题意
省略
思路
两层循环枚举取的名字和可能冲突的名字,查看是否存在一行两个名字与其他行名字重复
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
typedef long long ll;
vector<int> A,B,C;
int val[N];
int main(){
int n,x,y;
cin>>n>>x>>y;
for(int i = 0;i<n;i++){
cin>>val[i];
if(val[i]==x) A.push_back(i);
if(val[i]==y) B.push_back(i);
if(val[i]>x||val[i]<y)C.push_back(i);
}
ll sum = 0;
//for(int i:A) cout<<i<<" ";cout<<endl;
// for(int i:B) cout<<i<<" ";cout<<endl;
for(int i = 0;i<n;i++){ // 枚举右端点
int big = upper_bound(C.begin(),C.end(),i)-C.begin()-1;
int m = upper_bound(A.begin(),A.end(),i)-A.begin()-1;
int k = upper_bound(B.begin(),B.end(),i)-B.begin()-1;
if(m>=0&&k>=0&&val[A[m]]==x&&val[B[k]]==y){
int pos = min(A[m],B[k]);
// cout<<big<<" "<<pos<<'\n';
big = big==-1?-1:C[big];
if(big<pos){
sum += pos-big;
}
}
}
cout<<sum<<endl;
return 0;
}
C - 1 2 1 3 1 2 1
题意
定义Sn, n为1时,S1 = “1”,n>1时,Sn = Sn-1 + n + Sn-1;
例如S3 = 1 2 1 3 1 2 1
思路
记忆化搜索 , 跟着题目的意思搜一遍,途中记录每个Sn的字符串
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
typedef long long ll;
string S[N];
string dfs(int x){
if(x==1) {
return S[1] = "1";
}
if(S[x]!="") return S[x];
string s = dfs(x-1);
s+=" ";
if(x<10) s+=(x+'0');
else {
s += "1";
int y=x%10;
s+=(y+'0');
}
s+=" ";
s+=dfs(x-1);
return S[x] = s;
}
int main(){
int n;
cin>>n;
dfs(n);
cout<<S[n];
return 0;
}
E - Max Min
题意
给出n长度数组,问你有多少个区间【L,R】,中最大值为x,最小值为y
思路
二分,先记录x,y和大于x且小于y的下标(即不合法的下标),枚举右端点R,然后找R前面最近的x和y下标index_x,index_y ,和不合法的下标index_k,如果说最大值和最小值都找的到,那么以R为右端点的区间个数为 min(index_x,index_y) - index_k,就是包含最大最小值的位置到上一个不合法的位置
其中,还包含一些细节,比如找下标时index_x和index_y都大于0表示存在
还有上一个不合法位置不存在时把它赋值为-1
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
typedef long long ll;
vector<int> A,B,C;
int val[N];
int main(){
int n,x,y;
cin>>n>>x>>y;
for(int i = 0;i<n;i++){
cin>>val[i];
if(val[i]==x) A.push_back(i);
if(val[i]==y) B.push_back(i);
if(val[i]>x||val[i]<y)C.push_back(i);
}
ll sum = 0;
for(int i = 0;i<n;i++){ // 枚举右端点
int big = upper_bound(C.begin(),C.end(),i)-C.begin()-1;
int m = upper_bound(A.begin(),A.end(),i)-A.begin()-1;
int k = upper_bound(B.begin(),B.end(),i)-B.begin()-1;
if(m>=0&&k>=0&&val[A[m]]==x&&val[B[k]]==y){
int pos = min(A[m],B[k]);
big = big==-1?-1:C[big];
if(big<pos){
sum += pos-big;
}
}
}
cout<<sum<<endl;
return 0;
}