2017-11-8离线赛总结 (NOIP七连测第六场)

来源:互联网 发布:corelpainter for mac 编辑:程序博客网 时间:2024/05/22 08:21

失分小结:
估分:160
实际分数:170
今天身体不舒服,第三题理所当然地爆零了搞起来状态好就会写一样
前面两题还过得去,该水的分都水到了,只是第二题的正解敲了半天没调出来有些可惜还是代码功底弱的原因
第一题:
感觉自己的写法有些鬼畜瞎凑出答案
bfs+dfs,
bfs保证每步最优,dfs求联通块

struct node{int x,y,sp;};queue<node>q;int mp[1005][1005];bool mark[1005][1005];int step[1005][1005];int n,m;int cx[]={0,1,-1,0,1,1,-1,-1};int cy[]={1,0,0,-1,1,-1,1,-1};void dfs(int x,int y,int sp){    for(int i=0;i<8;i++){        int nx=x+cx[i],ny=y+cy[i];        if(nx<=0||ny<=0||nx>n||ny>n||mark[nx][ny])continue;        if(mp[nx][ny]!=mp[x][y])continue;        mark[nx][ny]=1;        dfs(nx,ny,sp);        q.push((node){nx,ny,sp});    }} void BFS(){    for(int i=1;i<=n;i++){        if(!mark[1][i]){            q.push((node){1,i,0});            mark[1][i]=1;            dfs(1,i,0);        }        if(!mark[1][n]){            q.push((node){1,n,0});            mark[1][n]=1;            dfs(1,n,0);        }        if(!mark[i][1]){            q.push((node){i,1,0});            mark[i][1]=1;            dfs(i,1,0);        }        if(!mark[n][i]){            q.push((node){n,i,0});            mark[n][i]=1;             dfs(n,i,0);        }    }    while(!q.empty()){        node now=q.front();q.pop();        int x=now.x,y=now.y;        step[x][y]=now.sp;        FOR(i,0,7){            int nx=x+cx[i],ny=y+cy[i];            if(!nx||!ny||nx>n||ny>n||mark[nx][ny])continue;            mark[nx][ny]=1;            if(!mp[x][y]){                dfs(nx,ny,now.sp);                q.push((node){nx,ny,now.sp});            }            else {                dfs(nx,ny,now.sp+1);                q.push((node){nx,ny,now.sp+1});            }        }    }}int main(){    scanf("%d%d",&n,&m);    FOR(i,1,n){        char C[1005];        scanf("%s",C+1);        FOR(j,1,n){            mp[i][j]=C[j]-'0';        }    }    BFS();    while(m--){        int x,y;        scanf("%d%d",&x,&y);        printf("%d ",step[x][y]);    }    puts("");    return 0;}

突然发现这几次较难的第一题都能被gang出来沾沾自喜


第二题:
这道题就比较正常了,
模拟可以水30分,然后优化就60分。然后考虑单点贡献,对于每一个点
都可以算出包含它并使其有效的区间,然后记录每一种颜色的有效范围区间
以上思路由Isrothy给出

#include<bits/stdc++.h>using namespace std;#define FOR(i,x,y) for(int i=(x);i<=(y);i++)#define DOR(i,x,y) for(int i=(x);i>=(y);i--)#define P 19900907#define M 1105#define ll long longbool mark[M*M];struct node{int l,r;}T[M*M];int main(){    int n,m,a;    ll ans=0;    scanf("%d%d",&n,&m);    FOR(i,1,n)FOR(j,1,m){        scanf("%d",&a);        if(!mark[a]){            ans+=(n-i+1)*(m-j+1);            ans%=P;            mark[a]=1;            T[a].l=j,T[a].r=m;        }        else {            if(j>T[a].r)continue;            if(T[a].l<=j&&j<=T[a].r){                ans-=(n-i+1)*(T[a].r-j+1);                ans%=P;                T[a].l=j;            }            else{                ans-=(m-j)*(n-i+1);                ans+=(T[a].l-j+1)*(n-i+1);                ans%=P;                T[a].r=T[a].l,T[a].l=j;            }        }    }    printf("%lld\n",(ans+P)%P);    return 0;}

第三题没有写出来主要是因为没有很好地理解最短路算法当初模板全靠背
再算最短路的时候,我们可以得到到每个点的时间,然后当我们已经到达某点并一到达此点所需的其他点时,把它加进队列中裸的模板题ni

#include<bits/stdc++.h>using namespace std;#define N 3005struct node{    long long v;int to;    bool operator < (const node &_)const{        return v>_.v;    }};vector<int>Q[N];vector<node>edge[N];int degree[N];bool haved[N];long long dis[N];void dij(int s){    memset(dis,-1,sizeof(dis));    priority_queue<node>q;    dis[s]=0;    q.push((node){0,s});    while(!q.empty()){        node now=q.top();q.pop();        if(dis[now.to]!=now.v)continue;        if(degree[now.to]){            haved[now.to]=1;            continue;        }        for(int i=0;i<(int)Q[now.to].size();i++){            int y=Q[now.to][i];            degree[y]--;            if(!degree[y]&&haved[y]){                q.push((node){now.v,y});                dis[y]=now.v;            }        }        for(int i=0;i<(int)edge[now.to].size();i++){            int y=edge[now.to][i].to;            if(dis[y]==-1||dis[now.to]+edge[now.to][i].v<dis[y]){                dis[y]=dis[now.to]+edge[now.to][i].v;                q.push((node){dis[y],y});            }        }    }}int main(){    int n,m;    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        int a,b;long long c;        scanf("%d%d%lld",&a,&b,&c);        edge[a].push_back((node){c,b});    }    for(int i=1;i<=n;i++){        int x,a;        scanf("%d",&x);        degree[i]=x;        for(int j=1;j<=x;j++){            scanf("%d",&a);            Q[a].push_back(i);        }    }    dij(1);    printf("%lld\n",dis[n]);    return 0;}

距离NOIP还有2天 fighting!