2017-11-8离线赛总结

来源:互联网 发布:mac os最新版本 编辑:程序博客网 时间:2024/05/22 05:05

    • 题目
    • 失分小结
      • 估分
      • 实际分数
    • 题解
      • T1
        • P100
          • CODE
      • T2
        • P100
          • CODE
      • T3
        • P100
          • CODE

题目

3817,3818,3819

失分小结

估分

100+100+50=250

实际分数

10+100+0=110

这次炸的十分严重.
第一题题目看错……第三题记忆化搜索炸了

题解

T1

P100

我写的太垃圾了,仅供参考.

CODE
#include<cstdio>#include<memory.h>#include<queue>#define N 1005using namespace std;bool mp[N][N],mark[N][N];int ans[N][N];char chr[N];int n,k;struct node{int x,y;};queue<node>Q[2];int rx[]= { 1, 1, 1,-1,-1,-1, 0, 0};int ry[]= { 1,-1, 0, 1,-1, 0, 1,-1};int main() {    scanf("%d%d",&n,&k);    for(int i=1; i<=n; i++) {        scanf("%s",chr);        for(int j=1; j<=n; j++)            mp[i][j]=(chr[j-1]=='1');    }    memset(ans,63,sizeof ans);    for(int i=1; i<=n; i++) {        ans[1][i]=ans[n][i]=ans[i][1]=ans[i][n]=0;        Q[1].push((node) {1,i});        Q[1].push((node) {n,i});        Q[1].push((node) {i,1});        Q[1].push((node) {i,n});    }    int f=1;    for(; !Q[f].empty(); f^=1)while(!Q[f].empty()) {        int x=Q[f].front().x,y=Q[f].front().y;        int z=ans[x][y];        Q[f].pop();        if(mark[x][y])continue;        mark[x][y]=1;        for(int i=0; i<8; i++) {            int px=x+rx[i],py=y+ry[i];            if(px<1||px>n||py<1||py>n)continue;            if(mp[px][py]||!mp[x][y]) {                if(ans[px][py]>z) {                    ans[px][py]=z;                    Q[f].push((node) {px,py});                }            } else {                if(ans[px][py]>z+1) {                    ans[px][py]=z+1;                    Q[!f].push((node) {px,py});                }            }        }    }    int a,b;    k--;//  for(int i=1; i<=n; i++) {//      for(int j=1; j<=n; j++)//          printf("%d ",ans[i][j]);//      puts("");//  }    scanf("%d%d",&a,&b);    printf("%d",ans[a][b]);    while(k--) {        scanf("%d%d",&a,&b);        printf(" %d",ans[a][b]);    }    puts("");    return 0;}

T2

这是做的最好的一题…

P100

对于每一种资源,只有第一次出现时(被认为是稀有资源)和第二次出现时(被认为是普通资源)有意义,于是可以记录每种资源第一、二次出现的纵坐标,以及上次出现的横坐标。
对于当前资源,
①.若纵坐标出现在记录的第一次之前,则

ans+=(ix1[k])×(y2[k]y1[k])
然后更新x,y.
②.若纵坐标出现在记录第一次之后且在第二次之前,则
ans+=(ix1[k])×(y2[k]j)
然后更新y2.
这样会漏了第一、二次出现之间靠近底部的部分,最后加上.
想通了还是很水的.

CODE
#include<cstdio>#define P 19900907#define N 1105#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)int X1[N*N],Y1[N*N],Y2[N*N];long long ans=0;int main() {    int n,m;    scanf("%d %d",&n,&m);    FOR(i,1,n)FOR(j,1,m) {        int k;        scanf("%d",&k);        if(!X1[k]) {            X1[k]=i;            Y2[k]=m+1;            Y1[k]=j;        } else if(j<Y1[k]) {            ans=(ans+1ll*(i-X1[k])*(Y2[k]-Y1[k]))%P;            X1[k]=i;            Y2[k]=Y1[k];            Y1[k]=j;        } else if(j>=Y1[k]&&j<Y2[k]) {            ans=(ans+1ll*(i-X1[k])*(Y2[k]-j))%P;            Y2[k]=j;        }    }    FOR(k,1,n*m)if(X1[k])        ans=(ans+1ll*(n+1-X1[k])*(Y2[k]-Y1[k]))%P;    printf("%lld\n",ans);    return 0;}

T3

P100

CODE
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>#include<queue>#define N 3005#define M 70005#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)using namespace std;inline void rd(int &x) {    x=0;static char c;    while(c=getchar(),c<48);    do x=(x<<1)+(x<<3)+(c&15);    while(c=getchar(),c>47);}int To[M],Nxt[M],Len[M],Head[N],tot;struct node {    int x;long long v;    bool operator< (const node &_)const {        return v>_.v;    }};int n,m,mark[N],ED[N];long long dis[N];vector<int>edge[N];int main() {    rd(n),rd(m);    memset(dis,-1,sizeof dis);    int st,ed,len;    FOR(i,1,m) {        rd(st),rd(ed),rd(len);        To[++tot]=ed,Nxt[tot]=Head[st],Len[tot]=len,Head[st]=tot;    }    int k,x;    for(int i=1; i<=n; i++) {        rd(k);        mark[i]=k;        for(int j=1; j<=k; j++)rd(x),edge[x].push_back(i);    }    priority_queue<node>Q;    Q.push((node) {1,0});    dis[1]=0;    node tmp;    long long d;    while(!Q.empty()) {        tmp=Q.top();        Q.pop();        x=tmp.x,d=tmp.v;        if(dis[x]!=d)continue;        if(mark[x]) {            ED[x]=1;            continue;        }        if(x==n){            printf("%lld\n",d);            return 0;        }        for(int i=0; i<edge[x].size(); i++) {            int y=edge[x][i];            mark[y]--;            if(mark[y]==0&&ED[y]) {                dis[y]=d;                Q.push((node) {y,d});            }        }        for(int i=Head[x]; i; i=Nxt[i]) {            int y=To[i];            long long t=d+Len[i];            if(dis[y]==-1||dis[y]>t) {                dis[y]=t;                Q.push((node) {y,t});            }        }    }    return 0;}
原创粉丝点击