2018.8.19 集训

标签: 杂题

这里写图片描述
暴力的广搜 。。然后AC了

#include<bits/stdc++.h>
using namespace std;
const int xx[4]={0,1,-1,0},yy[4]={1,0,0,-1};
struct node{int x,y;};
queue<node>q;
int n,m,ans=0;
char cc,c[101][101];
bool inq[101][101],vis[101][101],ch[27];

void bfs(int x,int y){
    inq[x][y]=1; vis[x][y]=1;
    q.push((node){x,y});
    while(!q.empty()){
        node a=q.front(); q.pop();
        for(int i=0;i<4;i++){
            int nx=a.x+xx[i],ny=a.y+yy[i];
            if(!inq[nx][ny]&&c[nx][ny]==cc)
             {q.push((node){nx,ny}); vis[nx][ny]=1; inq[nx][ny]=1;}
            else if(!vis[nx][ny]&&c[nx][ny]!='.'&&!ch[c[nx][ny]-64])
                 {vis[nx][ny]=1; ans++; ch[c[nx][ny]-64]=1;}
        }
    }
}

int main(){
    freopen("president.in","r",stdin);
    freopen("president.out","w",stdout);
    cin>>n>>m; 
    c[0][0]=getchar(); cc=getchar(); c[0][0]=getchar();
    ch[cc-64]=1;
    memset(inq,0,sizeof(inq));
    memset(vis,0,sizeof(vis));
    memset(ch,0,sizeof(ch));
    memset(c,'.',sizeof(c));
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++) cin>>c[i][j];  
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
      if(c[i][j]==cc) {bfs(i,j); break;}
    printf("%d\n",ans); 
    return 0;  
}

这里写图片描述
如果一个右括号匹配了,那么它与目前栈顶未匹配左括号之间肯定全部匹配了。
所以匹配一个右括号,就随时更新ans的最大值。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000002;
int len,t,ans;
bool f;
int q[1000005];
string s;

int main(){
    freopen("bracket.in","r",stdin);
    freopen("bracket.out","w",stdout);
    cin>>s; s=' '+s; len=s.length(); 
    for(int i=1;i<len;i++){
        if(s[i]=='(') q[++t]=i;
        if(s[i]==')') {if(t) ans=max(ans,i-q[t-1]),t--; else q[0]=i;} 
    }
    printf("%d\n",ans);
    return 0;
}

这里写图片描述
这里写图片描述

#include<bits/stdc++.h>
using namespace std;
int n;
inline int read(){
    long long x=0,f=1; char c; c=getchar();
    while(c<'0'||c>'9') {if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0'; c=getchar();}
    return x*f;
}

int main(){
    freopen("hill.in","r",stdin);
    freopen("hill.out","w",stdout);
    n=read();
    vector<int> h(n);
    for(int i=0;i<n;i++) h[i]=read();
    vector<int>::iterator highest=max_element(h.begin(),h.end());
    vector<int> a(highest,h.end());
    a.reserve(n);
    copy(h.begin(),highest,a.end());

    vector<int> l(n,-1);
    for(int i=1;i<n;i++){
        int p=i-1;
        while(a[i]>a[p]) p=l[p];
        l[i]= a[i]==a[p] ? l[p]:p;
    }

    vector<int> r(n,n);
    vector<int> s(n,0);
    for(int i=n-2;i>=0;i--){
        int p=i+1;
        while(p<n&&a[i]>a[p]) p=r[p];
        if(p==n){r[i]=p; continue;}
        r[i]= a[i]==a[p]? r[p]:p;
        s[i]= a[i]==a[p]? s[p]+1:0;
    }

    long long ans=0;
    for(int i=0;i<n;i++){
        if(l[i]>=0) ans++;
        if(r[i]<n) ans++;
        if(r[i]>=n&&l[i]>0) ans++;
        ans+=s[i];
    }

    printf("%ld\n",ans);
    return 0;
}

再插一段我自己能懂的代码 ( 手动滑稽

#include<cstdio>
int t[1000002],h[1000002],l[1000002],r[1000002],cnt[1000002];
int main() {
    int n,p=0; long long ans=0; 
    scanf("%d",&n);
    for(int i=0;i<n;++i) scanf("%d",t+i);
    for(int i=1;i<n;++i)
     if(t[i]>t[p]) p=i;   //寻找最大值
    for(int i=0;i<=n;++i) h[i]=t[(i+p)%n];  //转环为链
    for(int i=1;i<=n;++i) {
        l[i]=i-1;                   //初始化为i左边第一个
        while(l[i]&&h[i]>=h[l[i]]) l[i]=l[l[i]];    //满足条件便递推
    }
    for(int i=n-1;i>=0;--i) {
        r[i]=i+1;                       //初始化为i右边第一个
        while(r[i]<n&&h[i]>h[r[i]]) r[i]=r[r[i]];  //满足条件便递推
        if(r[i]<n&&h[i]==h[r[i]]) {
            cnt[i]=cnt[r[i]]+1;         //递推count数组
            r[i]=r[r[i]];
        }
    }
    for(int i=0;i<n;++i) {
        ans+=cnt[i];   //至少能看到的组数
        if(h[i]<h[0]) {
            ans+=2;   //另外的两组
            if(!l[i]&&r[i]==n) ans--;   //特判是同一组的情况
        }
    }
    printf("%I64d\n",ans);
    return 0;
}

题解转自洛谷 Loner_Knowledge

版权声明:本文为MiaoZ_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/MiaoZ_/article/details/81909981