Codeforces Round # 605 (Div. 3) solution to a problem

Portal

A. Three Friends

The meaning of problems

Three to a number \ (A, B, C \) , each number can be \ (+ 1, -1 \) or unchanged, the number of operations for each asked at most once after \ (| a'-b '| + | a'-c '| + | b'-c' | \) minimum.

Thinking

Value after violent enumerate each operand, and then record the results of the smallest on the line

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int T,a[5];

int main(){
    scanf("%d",&T);
    while(T--){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        LL res=0x3f3f3f3f3f3f3f;
        for(int i=-1;i<=1;i++)
            for(int j=-1;j<=1;j++)
                for(int k=-1;k<=1;k++){
                    int x=a+i,y=b+j,z=c+k;
                    res=min(res,1ll*abs(x-y)+abs(x-z)+abs(y-z));
                }
        printf("%lld\n",res);
    }
    return 0;
}

B. Snow Walking Robot

The meaning of problems

Describe a path to a string, which requires as little as possible to delete characters from such \ ((0,0) \) to go down according to the excision string can back \ ((0,0) \) , and In addition to \ ((0,0) \) does not pass through a point twice

Thinking

Statistics 'U', 'R', 'D' number, 'L', denoted \ (the U-, R & lt, D, L \) . From \ ((0,0) \) starting to go back to \ ((0,0) \) , then obviously \ (U = D, R = L \) , you first need to make \ (U = D = min (the U-, D), R & lt = L = min (R & lt, L) \) , then follow the first, and then the right, then the next, and then left circle can be completed. At this time, to be noted that, if deletion \ (U = D = 0 \ ) or \ (R & lt L = 0 = \) , then of course it can only go one step back and then immediately, since in this case, only the original way back, if you take more, along the way point will be after two, so this special case must be judged out.

Code

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int T;
char s[MAXN];

int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%s",s+1);
        int n=strlen(s+1);
        int U=0,R=0,D=0,L=0;
        for(int i=1;i<=n;i++)
            if(s[i]=='U') U++;
            else if(s[i]=='R') R++;
            else if(s[i]=='D') D++;
            else if(s[i]=='L') L++;
        U=D=min(U,D);
        R=L=min(L,R);
        if(!U&&!D&&R&&L) L=R=1;
        if(!L&&!R&&U&&D) U=D=1;
        printf("%d\n",U+D+L+R);
        for(int i=1;i<=U;i++) printf("U");
        for(int i=1;i<=R;i++) printf("R");
        for(int i=1;i<=D;i++) printf("D");
        for(int i=1;i<=L;i++) printf("L");
        printf("\n");
    }
    return 0;
}

C. Yet Another Broken Keyboard

The meaning of problems

To a string \ (S \) , \ (K \) letters, Q \ (S \) of which contains only \ (K \) number of letters substring species.

Thinking

Suppose \ (s [i, j] \) legitimate, then it must substring legitimate, it will produce contributions answers \ (\ frac {(j- i + 1) (j-i + 2)} {2 } \) .
Therefore, each elected for a legitimate range, then the answer to accumulate up on the line.

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=2e5+10;
int n,k,can[300];
char s[MAXN],temp[10];

int main(){
    scanf("%d%d",&n,&k);
    scanf("%s",s+1);
    for(int i=1,x;i<=k;i++){
        scanf("%s",temp);
        can[temp[0]]=1;
    }
    LL ans=0;
    int j=0;
    for(int i=1;i<=n;i++){
        if(can[s[i]]) j++;
        else{
            ans+=1ll*j*(j+1)/2;
            j=0;
        }
    }
    ans+=1ll*j*(j+1)/2;
    printf("%lld\n",ans);
    return 0;
}

D. Remove One Element

The meaning of problems

To a sequence, you could be deleted up from a number of species, the longest continuous rise in the sub-Q sequence length.

Thinking

Set \ (f [i] [0/1 ] \) as with the first \ (I \) bits at the end, the number of undeleted / deleted the length of the longest continuous increase in the number sequence can be obtained.
First \ (f [i] [0 ] \) in this state do well, the length is the longest common subsequence rises continuously:
\ [F [I] [0] = F [I-. 1] [0] + 1 \ (a [i]>
a [i-1]) \\ f [i] [0] = 1 \ (a [i] \ le a [i-1]) \] and \ (f [i] [1] \) in this state is not difficult, it is clear there are two situations may arise in this state:
1. \ (a [i] \) have received a \ (a [i-1] \) at the end and deleted the maximum number of consecutive sub-sequences after rising.
2. \ (a [i] \) to at \ (a [i-2] \) after the end of the maximum increase of the number of not deleted contiguous subsequence, obviously this situation is \ (a [i- 1] \) deleted.
\ [F [i] [1 ] = f [i-1] [1] +1 \ (a [i]> a [i-1]) \\ f [i] [1] = f [i-2 ] [0] +1 \ (a [i]> a [i-2]) \\ f [i] [1] = 1 ( in any case) \]

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+10;
int n,a[MAXN],f[MAXN][2];

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int ans=0;
    for(int i=1;i<=n;i++){
        f[i][0]=f[i][1]=1;
        if(a[i]>a[i-1]){
            f[i][0]=f[i-1][0]+1;
            f[i][1]=f[i-1][1]+1;
        } 
        if(a[i]>a[i-2]) f[i][1]=max(f[i][1],f[i-2][0]+1);
        ans=max(ans,max(f[i][0],f[i][1]));
    }
    printf("%d\n",ans);
    return 0;
}

E. Nearest Opposite Parity

The meaning of problems

To a \ (n-\) Sequence number \ (A_1, A_2, ..., A_N \) , the first \ (I \) number can jump Jump time \ (i '= i-a_i (i- a_i \ geq 1) \) number or the \ (i '= i + a_i (i + a_i \ leq n) \) on the number, the least number of hops each asked several times, so that \ (a_i \) and \ (a_ {i '} \) of different parity.

Thinking

Logically speaking, this question can be solved by searching, but of course, will direct the search time out, and then I would add memory of WA, so I changed a way to build map again after a wide search can be resolved.
Talk about how to build map
if known \ (ans_i \) , then if \ (j + a_j = i \ ) and \ (a_j \% 2% 2 = a_i \) , so \ (ans_j = ans_i + 1 \
) so If \ (a_i \% I + 2 = {a_i} A_ \% 2 \) , then it may establish a \ (i + a_i-> i \ ) directed edge,
\ (I-a_i \) and \ ( i \) Similarly
apparently easy to \ (ans_i = 1 \) in all positions, you can start from these positions can be wide search

Code

#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int MAXN=2e5+10;
int n,a[MAXN],ans[MAXN];
int head[MAXN],to[MAXN*2],nxt[MAXN*2],tot=0;
queue<int> que;

void add(int u,int v){
    to[++tot]=v;nxt[tot]=head[u];head[u]=tot;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    memset(ans,0x3f,sizeof(ans));
    for(int i=1;i<=n;i++){
        if(i-a[i]>=1&&a[i-a[i]]%2==a[i]%2) add(i-a[i],i);
        if(i+a[i]<=n&&a[i+a[i]]%2==a[i]%2) add(i+a[i],i);
    }
    for(int i=1;i<=n;i++)
        if(i-a[i]>=1&&a[i-a[i]]%2!=a[i]%2||i+a[i]<=n&&a[i+a[i]]%2!=a[i]%2)
            ans[i]=1,que.push(i);
    while(!que.empty()){
        int u=que.front();que.pop();
        for(int i=head[u];i;i=nxt[i])
            if(ans[to[i]]>ans[u]+1){
                ans[to[i]]=ans[u]+1;
                que.push(to[i]);
            }
    }
    for(int i=1;i<=n;i++) printf("%d ",ans[i]==inf?-1:ans[i]);
    return 0;
}

F. Two Bracket Sequences

The meaning of problems

Two brackets to the sequence \ (s1, s2 \) , requires construction of a shortest sequence bracketed specification \ (ANS \) , and satisfies \ (s1, s2 \) of \ (ANS \) in sequence.

Thinking

Wide search
assumes that already have constructed a sequence \ ((i, J, k) \) :
\ (i \) : \ (s1 \) before \ (i \) bit is a subsequence of the current sequence
\ (j \) : \ (s2 \) before \ (j \) bit is a subsequence of the current sequence
\ (k \) : \ (k = left parenthesis - right parenthesis \)
then you need from \ ((0, 0, 0) \) configured to \ ((len_ {s1},
len_ {s2}, 0) \) If this point is regarded as the triplet of three-dimensional space, it is actually requested from the \ ((0,0 , 0) \) to \ ((len_ {s1}, len_ {s2}, 0) \) is the shortest path.
Because this from one point to another point distance is \ (1 \) , then find the shortest direct wide search.
Turning now to the relationship between two points
of known brackets sequence \ ((i, j, k) \) ,
1. if the sequence to add a '(' (can be understood as the point \ ((i, j, k ) \) to go to another point)
If \ (S1 [I +. 1] = '(', S2 [J +. 1] = '(' \) , may constitute a sequence \ ((I +. 1, J +. 1, K +. 1) \) (point \ ((I, J, K) -> (I +. 1, J +. 1, K +. 1) \) )
If \ (s1 [i + 1] = '(', s2 [j + 1] \ not = ' ( '\) , may constitute a sequence \ ((I +. 1, J, K +. 1) \) (point \ ((I, J, K) -> (I +. 1, J, K +. 1) \) )
If \ (S1 [I +. 1] \ Not = '(', S2 [J +. 1] = '(' \) , may constitute a sequence \ ((I, J +. 1, K +. 1) \) (point \ ((I, J, K) -> (I, J. 1 +, K +. 1) \) )
2. If you add a '') (at this time to the sequence \ (K \ GEQ 0 \) , because to regulate brackets sequence, any prefix right parenthesis can not be more than a left parenthesis)
if \ (S1 [I +. 1] = ')', S2 [J +. 1] = ')' \) , may constitute a sequence \ (( +. 1 I, J +. 1,. 1-K) \) (point \ ((i, j, k ) -> (i + 1, j + 1,. 1-K) \) )
If\ (S1 [I +. 1] = ')', S2 [J +. 1] \ Not = ')' \) , may constitute a sequence \ ((I +. 1, J, K-. 1) \) (point \ ( (I, J, K) -> (I +. 1, J, K-. 1) \) )
If \ (s1 [i + 1] \ not = ')', s2 [j + 1] = ')' \ ) , may constitute a sequence \ ((I, J +. 1, K-. 1) \) (point \ ((I, J, K) -> (I, J +. 1, K-. 1) \) )
then to \ ((0,0,0) \) as a starting point to conduct a wide search.
Recording a wide search path from the end point \ ((len_ {s1}, len_ {s2}, 0) \) Reverse constructed path, is the answer.

#include <bits/stdc++.h>
using namespace std;
char s1[210],s2[210];
int n,m;
struct  Node{
    int i,j,k;
}f[210][210][410];
queue<Node> que;

void bfs(){
    memset(f,-1,sizeof(f));
    f[0][0][0]=(Node){0,0,0};
    que.push((Node){0,0,0});
    while(!que.empty()){
        Node u=que.front();que.pop();
        int i=u.i,j=u.j,k=u.k,vi,vj,vk;
        vi=i+(s1[i+1]=='(');
        vj=j+(s2[j+1]=='(');
        vk=k+1;
        if(vk<=n+m&&f[vi][vj][vk].i==-1){
            f[vi][vj][vk]=u;
            que.push((Node){vi,vj,vk});
        }
        vi=i+(s1[i+1]==')');
        vj=j+(s2[j+1]==')');
        vk=k-1;
        if(vk>=0&&f[vi][vj][vk].i==-1){
            f[vi][vj][vk]=u;
            que.push((Node){vi,vj,vk});
        }
    }
}

int main(){
    scanf("%s%s",s1+1,s2+1);
    n=strlen(s1+1);
    m=strlen(s2+1);
    bfs();
    string ans;
    int i=n,j=m,k=0;
    while(i||j||k){
        Node u=f[i][j][k];
        if(k>u.k) ans="("+ans;
        else ans=")"+ans;
        i=u.i;j=u.j;k=u.k;
    }
    cout<<ans<<endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/BakaCirno/p/12034009.html