2019.8.18 Summary

T1 postman messenger 100/100

The meaning of problems

There is a postman to send things, the post office at node 1. His total of N-1 to send things, which are destination 2 ~ N. Because of the city's busy traffic, so all roads are one-way, a total of M roads, take some time through each road. The postman can only bring one thing. This N-1 while stocks seeking something and eventually returned to the post office requires a minimum amount of time.

It is easy to find we claim \ (\ sum_ {J =. 1} ^ n-\) dis [1] [j] + DIS [J] [. 1], it is contemplated run spfa, for dis [1] [j] can again SPFA but to solve dis [j] [1] has not been resolved, if run n times spfa significant overtime, but we can change ideas, establish an anti map, node 1 run spfa, then the node to the other point is the distance do not the distance to the node point.

Code

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
const int N=1010,M=100010;
int head[N][2],ver[M][2],edge[M][2],Next[M][2],d[N][2];
int n,m,tot1,tot2;
long long ans;
bool v[N];
queue<int> q;
void add(int x,int y,int z){
    ver[++tot1][0]=y;edge[tot1][0]=z;Next[tot1][0]=head[x][0],head[x][0]=tot1;
}
void add1(int x,int y,int z){
    ver[++tot2][1]=y;edge[tot2][1]=z;Next[tot2][1]=head[x][1],head[x][1]=tot2;
}
void spfa(){
    memset(d,0x3f,sizeof(d));
    d[1][0]=0,v[1]=1;
    q.push(1);
    while(q.size()){
        int x=q.front();q.pop();
        v[x]=0;
        for(int i=head[x][0];i;i=Next[i][0]){
            int y=ver[i][0],z=edge[i][0];
            if(d[y][0]>d[x][0]+z){
                d[y][0]=d[x][0]+z;
                if(!v[y]) q.push(y),v[y]=1;
            }
        }
    }
    while(!q.empty()) q.pop();
    memset(v,0,sizeof(v));
    d[1][1]=0,v[1]=1;
    q.push(1);
    while(q.size()){
        int x=q.front();q.pop();
        v[x]=0;
        for(int i=head[x][1];i;i=Next[i][1]){
            int y=ver[i][1],z=edge[i][1];
            if(d[y][1]>d[x][1]+z){
                d[y][1]=d[x][1]+z;
                if(!v[y]) q.push(y),v[y]=1;
            }
        }
    }
}
int main(){
    n=read();m=read();
    for(int i=1;i<=m;++i){
        int x,y,z;
        x=read();y=read();z=read();
        add(x,y,z);
        add1(y,x,z);
    }
    spfa();
    for(int i=1;i<=n;++i){
        ans+=d[i][0]+d[i][1];
    }
    printf("%lld",ans);
    return 0;
}

T2 knock bricks 70/100

The meaning of problems

N layer of bricks is placed in a recess in the uppermost layer of oil N brick, a brick decrease from top to bottom each time. Has a score of each brick, this brick can get knocked corresponding value, as shown in FIG.

If you want to knock the first brick layer i j, then, if i = 1, you can just knock it out; if i> 1, then you will need to knock down the i-1 th layer and the j-j + 1 brick.

You can now knock up to M brick, seeking to have scored the most number.

Dp a problem, began to think of a line by line dp is found, however, choose [i, j] would choose [i-1, j + 1 ] and [i, j] all the boxes above, it seems that no after-effects are not satisfied sex, how to do it?
When we find such a file input

4 5
2 2 3 4
8 2 7
2 3
49

We can go to think is not possible an a dp, from n columns to a dp so no aftereffect, we can define the state of f [i] [j] [k] represents the current in the i-th column is selected from the j-th a total of k election, state transition equation

f[i][j][k]=max(f[i+1][t][k-j]+s[i][j],f[i][j][k])

t>=j-1&&t<=n-i

S [i] [j] represents a j-th column before the i-th and

Code

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,f[55][55][3000],a[55][55],s[55][55];
int main(){
    scanf("%d %d",&n,&m);
    memset(f,-0x3f,sizeof(f));
    f[n+1][0][0]=0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            scanf("%d",&a[i][j]);
        }
    }   
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            s[j][i]=s[j][i-1]+a[i][j];
        }
    }
    for(int i=n;i>=1;--i){
        for(int j=0;j<=n-i+1;++j){
            for(int k=j;k<=m;++k){
                for(int t=max(j-1,0);t<=n-i;++t){
                    f[i][j][k]=max(f[i+1][t][k-j]+s[i][j],f[i][j][k]);
                }
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            ans=max(ans,f[i][j][m]);
        }
    }
    printf("%d",ans);
    return 0;
}

T3 equivalent expression 30/0

The meaning of problems

To give an expression and then expression of n, determines whether or equivalent

An analog big problem, with the number a, and modulo prevent overflow

#include<bits/stdc++.h>
using namespace std;
const int mod=10007;
char w[55],c[55];
int a[100],t1,t2,x,n;
long long ans[5],c1[55],c2[55],c3[55];
int power(int x,int y){
    int tmp=1;
    while(y){
        if(y&1) tmp=(tmp*x)%mod;
        x=(x*x)%mod;
        y>>=1;
    }
    return tmp%mod;
}
void clu(){
    int m1=c1[t2],n1=c1[t2-1],m2=c2[t2],n2=c2[t2-1],m3=c3[t2],n3=c3[--t2]; 
    switch(w[t1--]){
        case '+':c1[t2]=(n1+m1+mod)%mod; c2[t2]=(n2+m2+mod)%mod; c3[t2]=(n3+m3+mod)%mod; break;
        case '-':c1[t2]=(n1-m1+mod)%mod; c2[t2]=(n2-m2+mod)%mod; c3[t2]=(n3-m3+mod)%mod; break;
        case '*':c1[t2]=(n1*m1+mod)%mod; c2[t2]=(n2*m2+mod)%mod; c3[t2]=(n3*m3+mod)%mod; break;
        case '^':c1[t2]=power(n1,m1); c2[t2]=power(n2,m2); c3[t2]=power(n3,m3); break;
    }
}
void js(){
    x=0;
    for(int i=0;i<strlen(c);i++){
        if(c[i]=='a') {c1[++t2]=3;c2[t2]=7;c3[t2]=13;} 
        else if(isdigit(c[i])) x=x*10+c[i]-'0';
        else{
            if(x!=0){c1[++t2]=x;c2[t2]=x;c3[t2]=x;x=0;}
            if(a[c[i]]==0)continue;
            if(c[i]=='('||t1==0&&c[i]!=')') w[++t1]=c[i]; 
            else{ 
                if(a[c[i]]<a[w[t1]]){
                    if(c[i]!=')') w[++t1]=c[i]; 
                    else{ 
                        while(w[t1]!='('&&t1) clu();   
                        if(w[t1]=='(')t1--;
                    }
                }  
                else{
                    while(a[c[i]]>=a[w[t1]]&&t1) clu(); 
                    if(c[i]!=')') w[++t1]=c[i];
                }
            } 
        }
    }
    if(x!=0){c1[++t2]=x;c2[t2]=x;c3[t2]=x;x=0;}
    while (t1)clu();
}
int main(){
    a['(']=5;a[')']=1;a['^']=2;a['*']=a['/']=3;a['+']=a['-']=4;
    gets(c);
    scanf("%d",&n);
    js();
    gets(c);
    ans[1]=c1[1];ans[2]=c2[1];ans[3]=c3[1];
    for(int i=1;i<=n;++i){
        t1=t2=0;gets(c);js(); 
        if(ans[1]==c1[1]%mod&&ans[2]==c2[1]%mod&&ans[3]==c3[1]%mod) 
        printf("%c",i+64);
    }
    return 0;
} 

T4 diffusion 100/100

The meaning of problems

Talk about what an easy to misunderstand wrong ideas

To minimize the time, went shortest Manhattan distance with respect to each point, and then take the maximum value, it is the time (maxn + 1) / 2.

Code

#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<iostream>
#define ll long long
#define MX 55
using namespace std;
int d[MX][MX];
int x[MX],y[MX];
int ans=0;
int man=1<<30;
int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d %d",&x[i],&y[i]);
    }
    for(int i=1;i<=n;++i){
        for(int j=i+1;j<=n;++j){
            d[i][j]=d[j][i]=(abs(x[i]-x[j])+abs(y[i]-y[j]));
        }
    }
    for(int i=1;i<=n;++i){
        man=1<<30;
        for(int j=1;j<=n;++j){
            if(i==j) continue;
            man=min(d[i][j],man);
        }
        ans=max(ans,man);
    }
    printf("%d",(ans+1)/2);
    return 0;
}

Only 20 minutes to do so, why is it wrong?

Because each taking the smallest edge can make you miss some of the edge is no election must choose, do not choose it will lead to China Unicom block none, give you an example

If according to the above method will only to the red edge is selected, but the black side at least one selected from the group, which will lead to the communication link block is not so wrong.

Correct

A more ingenious methods can be considered to find a shortest longest distance in the Manhattan distance can-half may be determined Unicom disjoint-set or bfs.

Code

#include<bits/stdc++.h>
using namespace std;
int n,ans,l,r,cnt,fa[60],zx[60],zy[60];
int find(int x){
    if(x==fa[x]) return x;
    else return fa[x]=find(fa[x]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d %d",&zx[i],&zy[i]);
    }
    l=0,r=1e9;
    while(l<=r){
        int mid=(l+r)>>1;
        for(int i=1;i<=n;++i){
            fa[i]=i;
        }
        for(int i=1;i<=n;++i){
            for(int j=i+1;j<=n;++j){
                int dis=abs(zx[i]-zx[j])+abs(zy[i]-zy[j]);
                if(dis<=mid*2){
                    int fa1=find(i);
                    int fa2=find(j);
                    if(fa1!=fa2) fa[fa1]=fa2;
                }
            }
        }
        cnt=0;
        for(int i=1;i<=n;++i){
            if(fa[i]==i) cnt++;
        }
        if(cnt==1) r=mid-1;
        else l=mid+1;
    }
    printf("%d",l);
    return 0;
}

This question can additionally calculate the link between any two points in time, and minimum spanning tree (MST), the MST of the maximum side is the answer. Because the nature of the MST is one of the largest satisfy the minimum edge weight between any two points.

Summary, today's exam overall okay, equivalent expression tune for a long time, do not know how to use getline. . . For analog or unfamiliar, too little practice, the code is not strong, to write about this topic.

Guess you like

Origin www.cnblogs.com/donkey2603089141/p/11414998.html