一道非常简单的基础题
要求删除'.',我们可以直接扫描,将非’.‘的字符存进一个的新的字符串,然后进行输出
#include<bits/stdc++.h>
using namespace std;
signed main(){
string s,r;
cin>>s;
for(int i=0;i<s.size();i++){
if(s[i]!='.')r+=s[i];
}
cout<<r<<endl;
return 0;
}
要求构造一个序列,∑N3Ai=M,我们可以不断的拆解m,来构造,每次寻找一个>=m的值,它的次方为p,如果!=m,则p减一,然后当m小于3时,我们可以分类讨论,m=1和2的情况
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int n,m;
signed main(){
cin>>m;
int p=0;
vector<int>a;
while(m>0){
p=0;
while((pow(3,p))<m)p++;
if(pow(3,p)!=m)p--;
if(m<3){
if(m==1)a.push_back(0);
else if(m==2){
a.push_back(0);
a.push_back(0);
}
m=0;
break;
}
int u=(pow(3,p));
m-=u;
a.push_back(p);
}
cout<<a.size()<<endl;
for(int i=0;i<a.size();i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
这题不能用find函数,因为有q,次查询,O(nm)会超时
所以我们只能根据给出的x值来讨论,当x与被修改值不同时,
s[x]上的元素为某个abc的值,则将个数减一;
修改后s[x]的值同理判断
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int n,q;
string s,u="ABC";
//int x[N],c[N];
signed main(){
cin>>n>>q;
cin>>s;
int ans=0;
for(int i=0;i<s.size();i++){
if(s[i]=='A'&&s[i+1]=='B'&&s[i+2]=='C')ans++;
}
int x;char c;
while(q--){
cin>>x>>c;
x--;
if(s[x]!=c){
if(x==0){
if(s[x]=='A'&&s[x+1]=='B'&&s[x+2]=='C')ans--;
}
else if(x==n-1){
if(s[x]=='C'&&s[x-1]=='B'&&s[x-2]=='A')ans--;
}
else{
if((s[x]=='A'&&s[x+1]=='B'&&s[x+2]=='C')||(s[x]=='C'&&s[x-1]=='B'&&s[x-2]=='A')||(s[x]=='B'&&s[x-1]=='A'&&s[x+1]=='C'))ans--;
}
if(c=='A'&&s[x+1]=='B'&&s[x+2]=='C'){
ans++;
}
else if(c=='B'&&s[x-1]=='A'&&s[x+1]=='C')ans++;
else if(c=='C'&&s[x-1]=='B'&&s[x-2]=='A')ans++;
}
s[x]=c;
cout<<ans<<endl;
}
return 0;
}
这题想了好久,我想是因为可能栈很长时间都没有碰了
解法一:栈
根据题目的要求,i,j之间没有更高,从关系上来看是线性的
,从最后开始每个元素都将在它前面最接近的大于他的值之间的元素贡献1,
因此我们可以使用栈,如果此元素大于栈顶,那么栈顶元素的贡献就结束了,可以弹出,
然后将此元素存入栈中。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
int h[N],c[N],f[N],n;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>h[i];
}
vector<int>u;
for(int i=n;i>0;i--){
c[i]=u.size();
for(;u.size()>0&&u.back()<h[i];){
u.pop_back();
}
u.push_back(h[i]);
}
for(int i=1;i<=n;i++){
cout<<c[i]<<' ';
}
return 0;
}
解法二:线段树+dfs
用线段树来维护最大元素的下标,建立一个前缀和数组
我们用dfs深搜,采用分冶的方法,如果最大值的下标不是r,那么在(l,r]之间有更大值
所以我们可以在最大值将区间拆分,当此区间没有最大值,那么c[l]++,c[r]--;
#include<bits/stdc++.h>
#define ls id<<1
#define rs id<<1|1
using namespace std;
const int N=1e6;
int h[N],n,c[N];
struct tree{
int l,r,mx;
}tr[N];
void pushup(int id){
int x=tr[ls].mx,y=tr[rs].mx;
tr[id].mx=h[x]>=h[y]?x:y;
}
void build(int id,int l,int r){
tr[id]={l,r,l};
if(l==r)return ;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(id);
}
int query(int id,int l,int r){
if(l<=tr[id].l&&tr[id].r<=r){
return tr[id].mx;
}
int mid=(tr[id].l+tr[id].r)>>1;
int mx=-1,mi=-1;
if(l<=mid){
int x=query(ls,l,r);
if(h[x]>mx){
mi=x;
mx=h[x];
}
}
if(r>mid){
int x=query(rs,l,r);
if(h[x]>mx){
mi=x;
mx=h[x];
}
}
return mi;
}
void dfs(int l,int r){
if(l>=r)return;
int u=query(1,l+1,r);
if(u==r){
c[l]++;
c[r]--;
dfs(l,r-1);
}
else{
dfs(l,u);
dfs(u,r);
}
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>h[i];
build(1,1,n);
dfs(1,n);
for(int i=1;i<=n;i++){
c[i]+=c[i-1];
cout<<c[i]<<" ";
}
return 0;
}
to be continue