zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 4

    612A - The Text Splitting    20171121

    简单字符串处理题

    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,p,q;
    string s;
    void print(int _)
    {
        int k=_+(n-_*p)/q;
        printf("%d
    ",k);
        for(int i=0;i<_;i++)
          {
          for(int j=0;j<p;j++)
            printf("%c",s[i*p+j]);
          printf("
    ");
          }
        for(int i=_;i<k;i++)
          {
          for(int j=0;j<q;j++)
            printf("%c",s[_*p+(i-_)*q+j]);
          printf("
    ");
          }
    }
    int main()
    {
        scanf("%d%d%d",&n,&p,&q);
        cin>>s;
        for(int i=0;i*p<=n;i++)
          if((n-i*p)%q==0)
            return print(i),0;
        return printf("-1
    "),0;
    }
    View Code

    612B - HDD is Outdated Technology    20171121

    设(p_{f_i}=i),则有(ans=sum_{i=2}^{n}|p_i-p_{i-1}|)

    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define LL long long
    int n,f,p[200001];
    LL ans;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          scanf("%d",&f),p[f]=i;
        for(int i=2;i<=n;i++)
          ans+=1ll*abs(p[i]-p[i-1]);
        printf("%I64d
    ",ans);
        return 0;
    }
    View Code

    612C - Replace To Make Regular Bracket Sequence    20171121

    根据题意扫一遍就好了

    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<stack>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int ans;
    string s;
    stack<char>_;
    bool check(char a,char b)
    {
        if(a=='<' && b=='>')return true;
        if(a=='{' && b=='}')return true;
        if(a=='[' && b==']')return true;
        if(a=='(' && b==')')return true;
        return false;
    }
    int main()
    {
        cin>>s;
        for(int i=0;i<s.size();i++)
          {
          if(s[i]=='<')_.push('<');
          if(s[i]=='{')_.push('{');
          if(s[i]=='[')_.push('[');
          if(s[i]=='(')_.push('(');
          if(s[i]=='>' || s[i]=='}' || s[i]==']' || s[i]==')')
            if(!_.size())return printf("Impossible
    "),0;
            else ans+=!check(_.top(),s[i]),_.pop();
          }
        if(_.size())return printf("Impossible
    "),0;
        return printf("%d
    ",ans),0;
    }
    View Code

    612D - The Union of k-Segments    20171121

    将线段按左端点排序,通过优先队列(存储内容为线段的右端点)在每次访问一个线段时将已经无效的线段删去,获取仍有效的线段数即可

    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<queue>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct rua{int l,r;}a[1000001];
    priority_queue<int,vector<int>,greater<int> >q;
    bool cmp(rua x,rua y){return x.l<y.l || (x.l==y.l && x.r>y.r);}
    int n,k,ll,rr,INF=-1000000001;vector<int>ans[2];
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
          scanf("%d%d",&a[i].l,&a[i].r);
        sort(a+1,a+n+1,cmp);rr=INF;
        for(int i=1;i<=n;i++)
          {
          while(q.size() && q.top()<a[i].l)q.pop();
          if(q.size()<k)
            {
            if(rr!=INF)
              ans[0].push_back(ll),ans[1].push_back(rr);
            if(rr<a[i].l)rr=INF;
            ll=a[i].l;
            }
          q.push(a[i].r);
          while(q.size()>k)q.pop();
          if(q.size()==k)rr=max(rr,q.top());
          }
        if(rr!=INF)ans[0].push_back(ll),ans[1].push_back(rr);
        printf("%d
    ",ans[0].size());
        for(int i=0;i<ans[0].size();i++)
          printf("%d %d
    ",ans[0][i],ans[1][i]);
        return 0;
    }
    View Code

    612E - Square Root of Permutation    20180910

    把(q_i)看做是从(i)向(q_i)连一条有向边,那么可以发现这是一个所有点的入度、出度均为1的有向图,显然这个图是由若干个不相交的环组成的。可以发现,(p_i)和(i)肯定在一个环内,所以对每个(i),可以找出(i)所在循环节的大小。若循环节的大小(sz)为奇数,那么被遍历的所有点在原图就处于同一个大小为(sz)的环内。若(sz)为偶数,则需要另外一个大小同为(sz)的循环节与其组成大小为(2cdot sz)的环,直接模拟即可。答案无解当且仅当存在偶数(sz),使得长度为(sz)的循环节个数为奇数。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000001
    int n,p[N],q[N],c[N],s[N];
    bool vis[N];
    void Union(int x,int y,int sz)
    {
        s[sz]=0;
        for(int i=1;i<=sz;i++)
          q[x]=y,q[y]=p[x],x=p[x],y=p[y];
    }
    void rua(int x,int sz)
    {
        if(sz%2==0)
          if(s[sz]){Union(x,s[sz],sz);return;}
          else{s[sz]=x;return;}
        c[0]=x;
        for(int i=1,cur=p[x];cur!=x;c[i++]=cur,cur=p[cur]);
        for(int i=0;i<sz;i++)
          if(i*2<sz-1)q[c[i]]=c[i+(sz+1)/2];
          else q[c[i]]=c[i-(sz-1)/2];
    }
    void dfs(int cur,int sz)
    {
        vis[cur]=true;
        if(vis[p[cur]])rua(cur,sz);
        else dfs(p[cur],sz+1);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          scanf("%d",&p[i]);
        for(int i=1;i<=n;i++)
          if(!vis[i])dfs(i,1);
        for(int i=1;i<=n;i++)
          if(s[i])return printf("-1
    "),0;
        for(int i=1;i<=n;i++)
          printf("%d%c",q[i],i<n?' ':'
    ');
    }
    View Code

    612F - Simba on the Circle    20180911

    首先为了方便程序运行,先对a[i]进行离散化处理。

    设f[i]表示当小于等于a[i]的数全部选完之后,还要走几步结束

     g[i][j]表示当小于等于a[i]的数全部选完之后,选遍a[i]+1并最终走到j的步数,显然a[j]要满足a[j]=a[i]+1

    然后设d[i]是满足a[j]=i的j的集合,这样就有f[j]=min{g[j][d[i+1][k]]+f[d[i+1][k]]}

    问题就在于如何求g[i][j]

    可以发现,最优的走法有两种,一种是先顺时针走到j的前一项值为a[j]的数,然后再逆时针走到j,另一种则是先逆时针走,再顺时针走到j,两者对应的答案取最小值就好了

    思路大概就是这样,但是细节上有很多方面要处理,本弱就因为细节调了快一个小时_(:з」∠)_

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2001
    int n,m,s,a[N],p[N],f[N],l[N][N],nxt[N],di[N][N],g[N][N],dis[N][N],vis[N];
    vector<int>d[N];
    int check1(int op,int ed,int x)
    {
        if(ed<op)ed+=n;
        if(x<op)x+=n;
        return x<ed?(x-1)%n+1:op;
    }
    int check2(int op,int ed,int x)
    {
        if(ed<op)ed+=n;
        if(x<=op)x+=n;
        return x<ed?(x-1)%n+1:(ed-1)%n+1;
    }
    void print(int x)
    {
        if(x<0)printf("%d
    ",x);
        else printf("+%d
    ",x);
    }
    void rua(int k,int cur)
    {
        if(k==m)return;
        int i=cur?cur:s,cnt=0,P=di[cur][nxt[cur]];
        if(a[i]==k+1)print(0),vis[i]=1;
        while(i!=l[cur][nxt[cur]])
          {
          i+=P,i=(i+n-1)%n+1,cnt++;
          if(a[i]==k+1 && !vis[i])
            print(cnt*P),cnt=0,vis[i]=1;
          }
        P*=-1;
        while(i!=nxt[cur])
          {
          i+=P,i=(i+n-1)%n+1,cnt++;
          if(a[i]==k+1 && !vis[i])
            print(cnt*P),cnt=0;
          }
        rua(k+1,i);
    }
    int main()
    {
        memset(f,0x3f,sizeof(f));
        scanf("%d%d",&n,&s);
        for(int i=1;i<=n;i++)
          scanf("%d",&a[i]),p[i]=a[i];
        sort(p+1,p+n+1);
        m=unique(p+1,p+n+1)-p-1;
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            if(a[i]==p[j])
              {
              d[j].push_back(i);
              a[i]=j;break;
              }
        d[0].push_back(s);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            dis[i][j]=(j+n-i)%n;
        for(int i=0;i<m;i++)
          {
          int sz=d[i+1].size();
          for(auto j:d[i])
            for(int k=0;k<sz;k++)
              {
              int to=d[i+1][k];
              int last=check1(j,to,d[i+1][(k+sz-1)%sz]);
              g[j][to]=dis[j][last]+dis[to][last],l[j][to]=last,di[j][to]=1;
              last=check2(to,j,d[i+1][(k+1)%sz]);
              if(g[j][to]>dis[last][j]+dis[last][to])
                g[j][to]=dis[last][j]+dis[last][to],l[j][to]=last,di[j][to]=-1;
              if(j==to)
                g[j][to]=2*min(dis[j][d[i+1][(k+sz-1)%sz]],dis[d[i+1][(k+1)%sz]][j]),
                g[j][to]=min(g[j][to],n);
              if(i==0)g[0][to]=g[j][to],l[0][to]=l[j][to],di[0][to]=di[j][to];
              }
          }
        d[0].pop_back();
        d[0].push_back(0);
        for(auto i:d[m])f[i]=0;
        for(int i=m-1;i>=0;i--)
          for(auto j:d[i])
            for(auto k:d[i+1])
              if(f[j]>f[k]+g[j][k])
                f[j]=f[k]+g[j][k],nxt[j]=k;
        printf("%d
    ",f[0]);
        rua(0,0);
    }
    View Code
  • 相关阅读:
    git代码回退
    7 用两个栈实现队列
    《Java并发编程实战》学习笔记
    226. Invert Binary Tree
    Interface与abstract类的区别
    Override和Overload的区别
    Java面向对象的三个特征与含义
    String、StringBuffer与StringBuilder的区别
    Hashcode的作用
    Object有哪些公用方法
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/9621938.html
Copyright © 2011-2022 走看看