题解

24 条题解

  • 2
    @ 2017-10-13 23:11:19

    先bfs,注意一个储水厂可到达的沙漠地区肯定是连续的,之后做区间覆盖就好了。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    using namespace std;
    const int maxn=505;
    int dx[]={1,-1,0,0};
    int dy[]={0,0,-1,1};
    int n,m,h[maxn][maxn],ans;
    bool vis[maxn],vist[maxn][maxn];
    struct node{
        int l,r;
    }e[maxn];
    struct odd{
        int x,y;
    };
    queue <odd> q;
    
    bool cmp(const node &a,const node &b){
        if(a.l<b.l)return 1;
        else if(a.l==b.l)return a.r<b.r;
        return 0;
    }
    void bfs(int x){
        memset(vist,0,sizeof vist);
        odd st;
        st.x=1;st.y=x;
        q.push(st);vist[1][x]=1;
        while(!q.empty()){
            odd u=q.front();q.pop();
            if(u.x==n){
                vis[u.y]=1;
                if(e[x].r<u.y)e[x].r=u.y;
                if(!e[x].l)e[x].l=u.y,e[x].r=u.y;
                else if(e[x].l>u.y)e[x].l=u.y;
            }
            for(register int i=0;i<4;++i){
                int nx=u.x+dx[i];
                int ny=u.y+dy[i];
                if(nx<1||nx>n||ny<1||ny>m||h[nx][ny]>=h[u.x][u.y]||vist[nx][ny])continue;
                odd neww;
                neww.x=nx,neww.y=ny;q.push(neww);vist[nx][ny]=1;
            }
        }
    }
    
    
    int main(){
        scanf("%d%d",&n,&m);
        for(register int i=1;i<=n;++i){
            for(register int j=1;j<=m;++j){
                scanf("%d",&h[i][j]);
            }
        }
        for(register int i=1;i<=m;++i){
            bfs(i);
        }
        bool flag=0;int ct=0;
        for(register int i=1;i<=m;++i){
            if(!vis[i])++ct,flag=1; 
        }
        if(flag){
            printf("0\n%d",ct);
            return 0;
        }
        sort(e+1,e+m+1,cmp);
        int idx=1,s=1,t,cnt=0;
        while(s<=m){
            t=s;
            for(register int i=idx;i<=m;++i){
                if(e[i].l<=t){
                    if(e[i].r>=t)s=e[i].r;
                }
                else {
                    idx=i;break;
                }
            }
            cnt++;s++;
        }
        printf("1\n%d",cnt);
        
        return 0;
    } 
    
  • 0
    @ 2019-06-30 17:02:45
    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define mem(a,b) memset(a,b,sizeof(a))
    #define REP(i,a,b) for(int i = a; i <= b; ++i)
    #define PER(i,a,b) for(int i = a; i >= b; --i)
    #define PB push_back
    #define MP make_pair
    #define fi first
    #define se second
    typedef long long LL;
    typedef double DB;
    
    const int maxn = 500;
    
    int n, m;
    int seg[maxn*maxn+5];
    int hi[maxn+5][maxn+5];
    int L[maxn+5][maxn+5], R[maxn+5][maxn+5];
    
    struct Node {
        int l, r, id;
        Node() {}
        Node(int _l, int _r, int _id) : l(_l), r(_r), id(_id) {}
        bool operator<(const Node &a) {
            return l < a.l;
        }
    } fk[maxn+5];
    
    void Min(int &a, int b) { a = min(a,b); }
    void Max(int &a, int b) { a = max(a,b); }
    
    const int walk[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
    bool vi[maxn+5][maxn+5];
    int bfs(int top) {
        queue<int> q;
        REP(i,1,top) q.push(1000 + seg[i]), vi[1][seg[i]] = 1;
        while(!q.empty()) {
            int x = q.front()/1000, y = q.front()%1000;
            q.pop();
            for(int t = 0; t < 4; ++t) {
                int xx = x + walk[t][0];
                int yy = y + walk[t][1];
                if(xx<1 || xx>n || yy<1 || yy>m) continue;
                if(vi[xx][yy] || hi[xx][yy]>=hi[x][y]) continue;
                vi[xx][yy] = 1;
                q.push(xx*1000 + yy);
            }
        }
        int res = 0;
        REP(i,1,m) res += (vi[n][i]==0);
        return res;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        int top = 0;
        REP(i,1,n) REP(k,1,m) {
            scanf("%d", &hi[i][k]);
            seg[++top] = i*1000 + k;
        }
        sort(seg+1, seg+1+top, [&](int a, int b) { return hi[a/1000][a%1000]<hi[b/1000][b%1000]; } );
        REP(i,1,top) {
            int x = seg[i]/1000, y = seg[i]%1000;
            if(x==n) L[x][y] = R[x][y] = y;
            else L[x][y] = m+10, R[x][y] = -1;
            for(int t = 0; t < 4; ++t) {
                int xx = x + walk[t][0];
                int yy = y + walk[t][1];
                if(xx<1 || xx>n || yy<1 || yy>m || hi[xx][yy]>=hi[x][y]) continue;
                Min(L[x][y], L[xx][yy]);
                Max(R[x][y], R[xx][yy]);
            }
        }
        REP(i,1,m) fk[i] = Node(L[1][i], R[1][i], i);
        sort(fk+1, fk+1+m);
        int pt = 1, now = 0;
        top = 0;
        priority_queue<pair<int,int>> q;
        while(now<m) {
            while(pt<=m && fk[pt].l<=now+1) {
                q.push( pair<int,int>(fk[pt].r, fk[pt].id) );
                ++pt;
            }
            if(q.empty() || q.top().fi<=now) break;
            now = q.top().fi;
            seg[++top] = q.top().se;
            q.pop();
        }
        if(now<m) {
            top = 0;
            REP(i,1,m) seg[++top] = i;
        }
        int cnt = bfs(top);
        if(cnt) printf("0\n%d\n", cnt);
        else printf("1\n%d\n", top);
        return 0;
    }
    
  • 0
    @ 2017-10-13 23:09:03
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int LIM=503;
    struct Stage{
        int l,r;
        Stage():l(INF),r(-INF){}
        inline bool operator < (Stage r) const
        {
            return l<r.l;
        }
    }S[LIM];
    int n,m,M[LIM][LIM],f[LIM],cnt=0;
    bool vis[LIM][LIM],ans[LIM];
    
    void dfs(int x,int y,int ori)
    {
        vis[x][y]=1;
        if(x==m){
            ans[y]=1;
            S[ori].l=min(S[ori].l,y);
            S[ori].r=max(S[ori].r,y);
        }
        if(M[x+1][y]<M[x][y]&&x!=m&&!vis[x+1][y]) dfs(x+1,y,ori);
        if(M[x-1][y]<M[x][y]&&x!=1&&!vis[x-1][y]) dfs(x-1,y,ori);
        if(M[x][y+1]<M[x][y]&&y!=n&&!vis[x][y+1]) dfs(x,y+1,ori);
        if(M[x][y-1]<M[x][y]&&y!=1&&!vis[x][y-1]) dfs(x,y-1,ori);
    }
    int main()
    {
        scanf("%d%d",&m,&n);
        memset(f,63,sizeof f);
        f[0]=0;
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
                scanf("%d",&M[i][j]);
        for(int i=1;i<=n;++i)
        {
            memset(vis,0,sizeof vis);       
            dfs(1,i,i);
        }
        for(int i=1;i<=n;++i)
            if(!ans[i]) ++cnt;
        if(cnt) printf("0\n%d",cnt);
        else{
            printf("1\n");
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j){
                    if(i>=S[j].l&&i<=S[j].r) f[i]=min(f[i],f[S[j].l-1]+1);
                }
            printf("%d",f[n]);
        }
        
        return 0;
    }
    
  • 0
    @ 2016-10-25 10:59:09

    TM这是我第一次接触区间覆盖问题。。。
    不过搞清楚之后觉得这个提高组最后一题有点水啊。。。
    测试数据 #0: Accepted, time = 0 ms, mem = 4144 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 4144 KiB, score = 10
    测试数据 #2: Accepted, time = 15 ms, mem = 4140 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 4140 KiB, score = 10
    测试数据 #4: Accepted, time = 15 ms, mem = 4144 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 4148 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 4152 KiB, score = 10
    测试数据 #7: Accepted, time = 0 ms, mem = 4156 KiB, score = 10
    测试数据 #8: Accepted, time = 15 ms, mem = 4168 KiB, score = 10
    测试数据 #9: Accepted, time = 46 ms, mem = 4208 KiB, score = 10
    Accepted, time = 91 ms, mem = 4208 KiB, score = 100

  • 0
    @ 2016-09-29 22:19:49

    这是一个区间完全覆盖问题

  • 0
    @ 2016-08-24 16:09:31

    水题水一发
    ```c++
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;

    const int INF = 1000000000;
    const int maxn = 500 + 10;

    struct Block {
    int L, R;
    bool operator < (const Block& rhs) const {
    return L < rhs.L;
    }
    };

    int n, m;
    int ans;
    int vis[maxn];
    int vis1[maxn][maxn];
    int hg[maxn][maxn];
    Block blocks[maxn];

    const int dr[] = { -1, 1, 0, 0};
    const int dc[] = { 0, 0, 1, -1};

    void dfs (int r, int c, int n_block) {
    if (r == n) {
    if (!vis[c]) { vis[c] = 1; ans--;}
    blocks[n_block].L = min(blocks[n_block].L, c);
    blocks[n_block].R = max(blocks[n_block].R, c);
    }
    vis1[r][c] = n_block;
    for (int d = 0; d < 4; d++)
    if (hg[r][c] > hg[r+dr[d]][c+dc[d]] && vis1[r+dr[d]][c+dc[d]] != n_block)
    dfs(r+dr[d], c+dc[d], n_block);
    }

    int solve () {
    int cnt = 0;
    sort(blocks+1, blocks+m+1);
    int L = 1, k = 1;
    while (L <= m) {
    cnt++;
    int R = L;
    for ( ; k <= m; k++) {
    if (blocks[k].L > L) break;
    R = max(R, blocks[k].R);
    }
    L = R + 1;
    }
    return cnt;
    }

    int main ()
    {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
    scanf("%d", &hg[i][j]);

    for (int i = 1; i <= n; i++) hg[i][0] = hg[i][m+1] = INF;
    for (int j = 1; j <= m; j++) hg[0][j] = hg[n+1][j] = INF;

    ans = m;
    for (int i = 1; i <= m; i++) {
    blocks[i].L = INF; blocks[i].R = -1;
    if ((i == 1 || i == m) || (hg[1][i] >= hg[1][i-1] && hg[1][i] >= hg[1][i+1]))
    dfs(1, i, i);
    }

    if (ans > 0) printf("0\n%d\n", ans);
    else printf("1\n%d\n", solve());
    return 0;
    }
    ```

  • 0
    @ 2016-07-23 11:09:50

    求最小区间覆盖贪心即可啊。

  • 0
    @ 2016-06-30 17:51:51

    其实只要一遍DFS就全求出来了。。。(然而区间覆盖写BFS用了临接表让我怀疑自己的脑袋。。。)
    顺便问一下#2是什么为什么一直RE好不解。。。
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define MAXN 510
    using namespace std;

    int n,m;
    int map[MAXN][MAXN];

    int l[MAXN][MAXN],r[MAXN][MAXN];
    int vis[MAXN][MAXN];
    int can[MAXN];

    int xx[4]={1,0,-1,0};
    int yy[4]={0,1,0,-1};

    void dfs(int x,int y)
    {
    if(vis[x][y])return ;
    vis[x][y]=1;
    for(int i=0;i<4;i++)
    if(map[x][y]>map[x+xx[i]][y+yy[i]])
    {
    dfs(x+xx[i],y+yy[i]);
    l[x][y]=min(l[x][y],l[x+xx[i]][y+yy[i]]);
    r[x][y]=max(r[x][y],r[x+xx[i]][y+yy[i]]);
    }
    if(x==n)
    {
    l[x][y]=min(l[x][y],y);
    r[x][y]=max(r[x][y],y);
    }
    }

    int pos=0;
    int fst[MAXN],next[MAXN*MAXN],to[MAXN*MAXN],poi=0;
    void add(int op,int ed)
    {next[++poi]=fst[op],fst[op]=poi,to[poi]=ed;return ;}
    void build()
    {
    for(int i=0;i<pos;i++)
    for(int j=i+1;j<pos;j++)
    {
    if(l[1][can[j]]<=r[1][can[i]]+1)add(can[i],can[j]);
    else break;
    }
    }

    int q[MAXN],inq[MAXN];
    int dep[MAXN];
    int bfs()
    {
    memset(dep,0x7f,sizeof(dep));
    int t=0,h=0,now;
    while(l[1][can[t]]==1&&t<pos)q[t]=can[t],dep[can[t]]=1,inq[can[t]]=1,t++;
    while(t!=h)
    {
    now=q[h++],h%=MAXN;
    if(r[1][now]==m)return dep[now];
    for(int i=fst[now];i;i=next[i])
    {
    if(dep[to[i]]>dep[now]+1)
    {
    dep[to[i]]=dep[now]+1;
    if(!inq[to[i]])q[t++]=to[i],inq[to[i]]=1,t%=MAXN;
    }
    }
    }
    return 0;
    }

    int main()
    {
    scanf("%d%d",&n,&m);
    memset(map,0x7f,sizeof(map));
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    scanf("%d",&map[i][j]);
    memset(l,0x7f,sizeof(l));
    memset(r,0,sizeof(r));
    for(int i=1;i<=m;i++)
    dfs(1,i);

    int cnt=0;
    bool flag=false;
    for(int i=1;i<=m;i++)
    {
    if(!flag&&r[1][i]!=0)can[pos++]=i;
    if(!vis[n][i])
    {
    flag=true;
    cnt++;
    }
    }
    if(flag)
    printf("0\n%d\n",cnt);
    else
    {
    build();
    printf("1\n%d\n",bfs());
    }

    return 0;
    }

  • 0
    @ 2016-06-17 13:45:35

    详细题解http://blog.csdn.net/Balala_Energy/article/details/51227646
    ```c++
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <climits>
    using namespace std;
    const int L=501;
    const int INF=INT_MAX;
    int n,m; int map[L][L]; int F[L],LEFT[L],RIGHT[L];//main
    struct zk { int x,y; }; queue<zk> q; bool used[L][L];//bfs
    bool LEFTused[L][L],RIGHTused[L][L];//dfs
    void read()
    {
    int i,j;
    scanf("%d%d",&n,&m);
    for (i=1;i<=m;i++)
    F[i]=INF;
    F[1]=1;
    for (i=1;i<=n;i++)
    for (j=1;j<=m;j++)
    scanf("%d",&map[i][j]);
    return;
    }
    bool bfs()
    {
    while(!q.empty()) q.pop();
    zk temp; temp.y=1; int a,b,i;
    for (i=1;i<=m;i++)
    {
    temp.x=i;
    q.push(temp);
    used[1][i]=1;
    }
    while(!q.empty())
    {
    temp=q.front();
    a=temp.y; b=temp.x;
    if (a>1&&!used[a-1][b]&&map[a][b]>map[a-1][b])
    {
    temp.y=a-1; temp.x=b;
    q.push(temp); used[a-1][b]=1;
    }
    if (a<n&&!used[a+1][b]&&map[a][b]>map[a+1][b])
    {
    temp.y=a+1; temp.x=b;
    q.push(temp); used[a+1][b]=1;
    }
    if (b>1&&!used[a][b-1]&&map[a][b]>map[a][b-1])
    {
    temp.y=a; temp.x=b-1;
    q.push(temp); used[a][b-1]=1;
    }
    if (b<m&&!used[a][b+1]&&map[a][b]>map[a][b+1])
    {
    temp.y=a; temp.x=b+1;
    q.push(temp); used[a][b+1]=1;
    }
    q.pop();
    }
    for (i=1;i<=m;i++)
    if (!used[n][i])
    return 0;
    return 1;
    }
    void dfs1(int num,int x,int y,int front)
    {
    if(LEFTused[x][y]==1) return;
    LEFTused[x][y]=1;
    if(x==1) LEFT[y]=num;
    if(x-1>=1&&front!=2&&map[x-1][y]>map[x][y]) dfs1(num,x-1,y,1);
    if(x+1<=n&&front!=1&&map[x+1][y]>map[x][y]) dfs1(num,x+1,y,2);
    if(y-1>=1&&front!=4&&map[x][y-1]>map[x][y]) dfs1(num,x,y-1,3);
    if(y+1<=m&&front!=3&&map[x][y+1]>map[x][y]) dfs1(num,x,y+1,4);
    return;
    }
    void dfs2(int num,int x,int y,int front)
    {
    if(RIGHTused[x][y]==1) return;
    RIGHTused[x][y]=1;
    if(x==1) RIGHT[y]=num;
    if(x-1>=1&&front!=2&&map[x-1][y]>map[x][y]) dfs2(num,x-1,y,1);
    if(x+1<=n&&front!=1&&map[x+1][y]>map[x][y]) dfs2(num,x+1,y,2);
    if(y-1>=1&&front!=4&&map[x][y-1]>map[x][y]) dfs2(num,x,y-1,3);
    if(y+1<=m&&front!=3&&map[x][y+1]>map[x][y]) dfs2(num,x,y+1,4);
    return;
    }
    void dp()
    {
    int i,j;
    for(i=2;i<=m;i++)
    for(j=1;j<=m;j++)
    {
    if(LEFT[j]<=i&&RIGHT[j]>=i)
    F[i]=min(F[i],F[LEFT[j]-1]+1);
    else if(LEFT[j]>i)
    break;
    }
    return;
    }
    void work()
    {
    int i,ans=0;
    if (!bfs())
    {
    for (i=1;i<=m;i++)
    if (!used[n][i])
    ans++;
    printf("0\n%d",ans);
    }
    else
    {
    for(i=1;i<=m;i++)
    dfs1(i,n,i,0);
    for(i=m;i>=1;i--)
    dfs2(i,n,i,0);
    dp();
    printf("1\n%d",F[m]);
    }
    return;

    }
    int main()
    {
    freopen("flow.in","r",stdin);
    freopen("flow.out","w",stdout);
    read();
    work();
    return 0;
    }
    ```

  • 0
    @ 2015-10-24 21:59:28

    第一次没有输入0和1直接爆零。。。。
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cstring>

    using namespace std;

    int n, m;
    int h[5 05][505];
    bool f0[505][505];
    int l[505], r[505];
    int f[505];
    int q[500005], x[500005], y[500005];

    void bfs2(int i, int X, int Y) {
    memset(x, 0, sizeof (x));
    memset(y, 0, sizeof (y));
    int now, end;
    now = end = 0;
    x[now] = X;
    y[now] = Y;
    while (now <= end) {
    int x0, y0;
    x0 = x[now];
    y0 = y[now];
    if (f0[x0][y0]) {
    ++now;
    continue;
    }
    f0[x0][y0] = true;
    if (x0 == n) {
    l[i] = min(l[i], y0);
    r[i] = max(r[i], y0);
    }
    if (h[x0][y0] > h[x0][y0 + 1] && y0 + 1 <= m) {
    x[++end] = x0;
    y[end] = y0 + 1;
    }
    if (h[x0][y0] > h[x0][y0 - 1] && y0 - 1 >= 1) {
    x[++end] = x0;
    y[end] = y0 - 1;
    }
    if (h[x0][y0] > h[x0 + 1][y0] && x0 + 1 <= n) {
    x[++end] = x0 + 1;
    y[end] = y0;
    }
    if (h[x0][y0] > h[x0 - 1][y0] && x0 - 1 >= 1) {
    x[++end] = x0 - 1;
    y[end] = y0;
    }
    ++now;
    }
    }
    void bfs1(int X, int Y) {
    memset(x, 0, sizeof (x));
    memset(y, 0, sizeof (y));
    int now, end;
    now = end = 0;
    x[now] = X;
    y[now] = Y;
    while (now <= end) {
    int x0, y0;
    x0 = x[now];
    y0 = y[now];
    if (f0[x0][y0]) {
    ++now;
    continue;
    }
    f0[x0][y0] = true;
    if (h[x0][y0] > h[x0][y0 + 1] && y0 + 1 <= m) {
    x[++end] = x0;
    y[end] = y0 + 1;
    }
    if (h[x0][y0] > h[x0][y0 - 1] && y0 - 1 >= 1) {
    x[++end] = x0;
    y[end] = y0 - 1;
    }
    if (h[x0][y0] > h[x0 + 1][y0] && x0 + 1 <= n) {
    x[++end] = x0 + 1;
    y[end] = y0;
    }
    if (h[x0][y0] > h[x0 - 1][y0] && x0 - 1 >= 1) {
    x[++end] = x0 - 1;
    y[end] = y0;
    }
    ++now;
    }
    }
    void dfs2(int i, int x, int y) {
    //printf("<<%d %d>>\n", x, y);
    if (f0[x][y])
    return ;
    f0[x][y] = true;
    if (x == n) {
    l[i] = min(l[i], y);
    r[i] = max(r[i], y);
    }
    if (h[x][y] > h[x][y + 1] && y + 1 <= m)
    dfs2(i, x, y + 1);
    if (h[x][y] > h[x][y - 1] && y - 1 >= 1)
    dfs2(i, x, y - 1);
    if (h[x][y] > h[x - 1][y] && x - 1 >= 1)
    dfs2(i, x - 1, y);
    if (h[x][y] > h[x + 1][y] && x + 1 <= n)
    dfs2(i, x + 1, y);
    }
    void dfs1(int x, int y) {
    if (f0[x][y])
    return ;
    f0[x][y] = true;
    if (h[x][y] > h[x][y + 1] && y + 1 <= m)
    dfs1(x, y + 1);
    if (h[x][y] > h[x][y - 1] && y - 1 >= 1)
    dfs1(x, y - 1);
    if (h[x][y] > h[x - 1][y] && x - 1 >= 1)
    dfs1(x - 1, y);
    if (h[x][y] > h[x + 1][y] && x + 1 <= n)
    dfs1(x + 1, y);
    }
    int main(int argc, const char *argv[]) {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
    scanf("%d", &h[i][j]);
    for (int i = 1; i <= m; ++i) {
    bfs1(1, i);
    }
    int ans0 = m;
    for (int i = 1; i <= m; ++i)
    ans0 -= f0[n][i];
    if (ans0) {
    printf("0\n%d\n", ans0);
    return 0;
    }
    for (int i = 1; i <= m; ++i) {
    memset(f0, 0, sizeof (f0));
    l[i] = 505;
    bfs2(i, 1, i);
    if (l[i] == 505) {
    l[i] = 505;
    r[i] = 505;
    }
    //printf("<%d %d>", l[i], r[i]);
    }
    for (int i = 1; i <= m; ++i) {
    f[i] = 1000000000;
    for (int j = 1; j <= m; ++j) {
    if (l[j] <= i && i <= r[j])
    f[i] = min(f[i], f[l[j] - 1] + 1);
    }
    }
    printf("1\n%d\n", f[m]);
    return 0;
    }

  • 0
    @ 2015-10-09 23:12:47

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int MAXN = 500 + 10;

    int h[MAXN][MAXN], vis[MAXN][MAXN], l[MAXN], r[MAXN], f[MAXN], got_w[MAXN];
    int n, m;
    int d1[5] = {0, 1, 0, -1};
    int d2[5] = {1, 0, -1, 0};

    struct Status{
    int x, y;
    }start;

    queue<Status> q;

    bool check(Status now, Status old){
    int s = now.x, t = now.y;
    if(vis[s][t] || s<1 || s>n || t<1 || t>m)
    return 1;
    if(h[s][t] >= h[old.x][old.y])
    return 1;
    return 0;
    }

    void init_Bfs(){
    for(int i=1; i<=m; i++){
    Status ne;
    ne.x = 1;
    ne.y = i;
    q.push(ne);
    vis[1][i] = 1;
    }
    while(!q.empty()){
    Status old = q.front();
    q.pop();
    for(int i=0; i<4; i++){
    Status now = old;
    now.x += d1[i];
    now.y += d2[i];
    if(check(now, old))
    continue;
    vis[now.x][now.y] = 1;
    q.push(now);

    }
    }
    }

    void Bfs(int s){
    start.x = 1;
    start.y = s;
    q.push(start);
    vis[1][s] = 1;
    while(!q.empty()){
    Status old = q.front();
    q.pop();
    for(int i=0; i<4; i++){
    Status now = old;
    now.x += d1[i];
    now.y += d2[i];
    if(check(now, old))
    continue;
    vis[now.x][now.y] = 1;
    q.push(now);

    }
    }
    }

    int main()
    {
    scanf("%d%d", &n, &m);
    for(int i=1; i<=n; i++)
    for(int j=1; j<=m; j++)
    scanf("%d", &h[i][j]);
    init_Bfs();
    for(int i=1; i<=m; i++)
    if(vis[n][i])
    got_w[i]++;
    int ans = 0;
    for(int i=1; i<=m; i++)

    if(!got_w[i])
    ans++;
    if(ans){
    printf("0\n%d", ans);
    return 0;
    }
    for(int i=1; i<=m; i++){
    memset(vis, 0, sizeof(vis));
    Bfs(i);
    r[i] = l[i] = 0;
    for(int j=1; j<=m; j++){
    if(vis[n][j] && !r[i] && !l[i]){
    l[i] = j;
    r[i] = j;
    }
    else if(vis[n][j] && !vis[n][j+1] && l[i]){
    r[i] = j;
    break;
    }
    }
    }
    for(int i=1; i<=m; i++)
    f[i] = 0x7fffffff;
    for(int i=1; i<=m; i++)
    for(int j=1; j<=m; j++)
    if(l[j] <=i && r[j] >= i)
    f[i] = min(f[l[j]-1]+1, f[i]);
    printf("1\n%d", f[m]);

    return 0;
    }
    两次BFS + DP

  • 0
    @ 2015-09-04 20:32:42

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define inf 1<<30
    using namespace std;
    int n,m,ans,now;
    int x1[5]={0,1,0,-1,0};
    int y1[5]={0,0,1,0,-1};
    int p[510][510],a[510][510];
    int f[510];
    struct qujian{
    int l,r;
    };
    qujian g[510];
    struct node{
    int x,y;
    };
    node q[250100];
    void bfs()
    {
    int head=0,tail=0;
    for(int i=1;i<=m;i++){
    p[1][i]=1;
    q[++tail].x=1;
    q[tail].y=i;
    }
    while(head<tail){
    node u=q[++head];
    for(int i=1;i<=4;i++){
    node v;
    v.x=u.x+x1[i];v.y=u.y+y1[i];
    if(v.x>n||v.x<1||v.y>m||v.y<1) continue;
    if(a[v.x][v.y]>=a[u.x][u.y]) continue;
    if(p[v.x][v.y]) continue;
    p[v.x][v.y]=1;
    q[++tail]=v;
    }
    }
    }
    void bdfs(int x,int y)
    {
    p[x][y]=1;
    if(x==n){
    g[now].l=min(g[now].l,y);
    g[now].r=max(g[now].r,y);
    }
    for(int i=1;i<=4;i++){
    int xx=x+x1[i],yy=y+y1[i];
    if(xx>n||xx<1||yy<1||yy>m) continue;
    if(a[xx][yy]>=a[x][y]) continue;
    if(!p[xx][yy])
    bdfs(xx,yy);
    }
    }
    int main()
    {
    freopen("flow.in","r",stdin);
    freopen("flow.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    scanf("%d",&a[i][j]);
    bfs();
    int ans=0;
    for(int i=1;i<=m;i++)
    if(!p[n][i])
    ans++;
    if(ans){
    printf("0\n");
    printf("%d",ans);
    return 0;
    }
    for(int i=1;i<=m;i++){
    memset(p,0,sizeof(p));
    now=i;
    g[now].l=m+1;
    g[now].r=0;
    bdfs(1,now);
    }
    f[0]=0;
    for(int i=1;i<=m;i++){
    f[i]=inf;
    for(int j=1;j<=m;j++)
    if(i>=g[j].l&&i<=g[j].r)
    f[i]=min(f[i],f[g[j].l-1]+1);
    }
    printf("1\n");
    printf("%d",f[m]);
    }

  • 0
    @ 2015-07-02 11:00:49

    难得又做出一道提高组最后一题...... 从样例中其实可以做出一个猜想:如果底层城市全都能被供水,那么对于任意一个蓄水站,它能供水的底层城市应当是一片连续的区域。这个猜想应该很好证明正确性,因为如果一个蓄水站供水的底层城市不是一片连续区域,那么中间就会出现”空缺“,这个“空缺”显然不可能由其它蓄水站来填补。因此解决这道题的思路是,先BFS判断是否有解,如果有解,用2次DFS+1次DP求解。

    BFS:假设每一个湖边城市都有蓄水站,找出所有能被供水的点并标记。如果底层全被标记,则有解。否则没有解,输出0和未 被标记的个数。

    DFS:用来找一个蓄水站供水的左边界和右边界。对于左边界,从底层1号开始搜索,能从底层K到到顶层某位置,则此位置供 水的左边界就是K。搜索时,已经过的点都不要再次经过。因为通过这些点要么无法到达顶层,要么到达顶层的左边界已 经确定且一定比现有的更小(举图中例子来说,底层1号经过高度为7的点到达顶层1号,顶层1号供水左边界为1号,那 么底层2号搜索时就不要再经过这个高度为7的点,因为通过它能到达的顶层1号,边界为1号,比2号小)。 对于右边 界则从底层K号开始,方法是一样的。用left[i]和right[i]表示i号蓄水站供水的左边界和右边界。

    DP:f[i]表示到底层i号为止需要的蓄水站数目,初始化f[0]=0,f[1]=1,其他为无穷大。
    可以得到下面这个式子:
    f[i]=min{f[left[v]-1]+1} (left[v]<=i,right[v]>=i)
    想法也比较简单,v蓄水站供水范围为left[v]~right[v],如果其中包含i,只需1个蓄水站就可对供水left[v]~i进行供水。那 么到i为止总共所需的蓄水站数量就为到left[v]前一个城市为止需要的蓄水站数量+1。当left[v]>i时直接跳出循环,去进行 i+1的循环(通过前面分析可知,left显然是一个不下降序列)。

    #include<stdio.h>
    int map[501][501],bools[501][501],left[501]={0},right[501]={0};
    int n,m;

    struct forbfs
    {
    int x,y;
    }q[5001];

    int min(int a,int b)
    {
    if(a<b) return a;
    else return b;
    }

    void bfs( )
    {
    int head=0,tail=m;
    int i,x,y;

    for(i=1;i<=m;i++)
    {
    q[i].x=1;
    q[i].y=i;
    bools[1][i]=1;
    }

    while(head!=tail)
    {

    head=(head+1)%5000;
    x=q[head].x;
    y=q[head].y;

    if(x-1>=1 && bools[x-1][y]==0 && map[x-1][y]<map[x][y])
    {
    bools[x-1][y]=1;
    tail=(tail+1)%5000;
    q[tail].x=x-1;
    q[tail].y=y;
    }

    if(x+1<=n && bools[x+1][y]==0 && map[x+1][y]<map[x][y])
    {
    bools[x+1][y]=1;
    tail=(tail+1)%5000;
    q[tail].x=x+1;
    q[tail].y=y;

    }

    if(y-1>=1 && bools[x][y-1]==0 && map[x][y-1]<map[x][y])
    {
    bools[x][y-1]=1;
    tail=(tail+1)%5000;
    q[tail].x=x;
    q[tail].y=y-1;
    }

    if(y+1<=m && bools[x][y+1]==0 && map[x][y+1]<map[x][y])
    {
    bools[x][y+1]=1;
    tail=(tail+1)%5000;
    q[tail].x=x;
    q[tail].y=y+1;
    }

    }
    }

    void dfs1(int num,int x,int y,int front)
    {
    if(bools[x][y]==1) return;

    bools[x][y]=1;

    if(x==1) left[y]=num;

    if(x-1>=1 && front!=2 && map[x-1][y]>map[x][y]) dfs1(num,x-1,y,1);
    if(x+1<=n && front!=1 && map[x+1][y]>map[x][y]) dfs1(num,x+1,y,2);
    if(y-1>=1 && front!=4 && map[x][y-1]>map[x][y]) dfs1(num,x,y-1,3);
    if(y+1<=m && front!=3 && map[x][y+1]>map[x][y]) dfs1(num,x,y+1,4);
    }

    void dfs2(int num,int x,int y,int front)
    {
    if(bools[x][y]==1) return;

    bools[x][y]=1;

    if(x==1) right[y]=num;

    if(x-1>=1 && front!=2 && map[x-1][y]>map[x][y]) dfs2(num,x-1,y,1);
    if(x+1<=n && front!=1 && map[x+1][y]>map[x][y]) dfs2(num,x+1,y,2);
    if(y-1>=1 && front!=4 && map[x][y-1]>map[x][y]) dfs2(num,x,y-1,3);
    if(y+1<=m && front!=3 && map[x][y+1]>map[x][y]) dfs2(num,x,y+1,4);
    }

    int main( )
    {
    int i,j,bfans=0,dp[501];

    scanf("%d %d",&n,&m);

    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    {
    scanf("%d",&map[i][j]);
    bools[i][j]=0;
    }

    //

    bfs( );

    for(i=1;i<=m;i++)
    if(bools[n][i]==0) bfans++;

    if(bfans!=0) {printf("0\n%d",bfans);goto endl;}

    //

    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    bools[i][j]=0;

    for(i=1;i<=m;i++)
    dfs1(i,n,i,0);

    //

    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    bools[i][j]=0;

    for(i=m;i>=1;i--)
    dfs2(i,n,i,0);

    //

    for(i=1;i<=m;i++)
    dp[i]=1000008;

    dp[0]=0;
    dp[1]=1;

    for(i=2;i<=m;i++)
    {
    for(j=1;j<=m;j++)
    {
    if(left[j]<=i && right[j]>=i) dp[i]=min(dp[i],dp[left[j]-1]+1);
    else if(left[j]>i) break;
    }
    }

    printf("1\n%d",dp[m]);

    //

    endl:return 0;
    }

  • 0
    @ 2014-11-30 17:14:14

    #include<algorithm>
    #include<cstring>
    #include<iostream>
    using namespace std;
    bool l[501][501],w[501];
    int e[501][501],f[501],m,n;
    class s
    {
    public:
    int l,r;
    s()
    {
    l=0x7fffffff;
    r=0;
    }
    }a[501];
    bool operator<(s a,s b)
    {
    return a.r<b.r;
    }
    void o(int s,int x,int y)
    {
    int h;
    if(x==n)
    {
    w[y]=1;
    a[s].l=min(a[s].l,y);
    a[s].r=max(a[s].r,y);
    }
    l[x][y]=1;
    h=e[x][y];
    if(x<n&&e[x+1][y]<h&&!l[x+1][y])
    o(s,x+1,y);
    if(x>1&&e[x-1][y]<h&&!l[x-1][y])
    o(s,x-1,y);
    if(y<m&&e[x][y+1]<h&&!l[x][y+1])
    o(s,x,y+1);
    if(y>1&&e[x][y-1]<h&&!l[x][y-1])
    o(s,x,y-1);
    }
    main()
    {
    int i,j,x=0,t=1;
    cin>>n>>m;
    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    cin>>e[i][j];
    for(i=1;i<=m;i++)
    {
    if(i>1&&e[1][i]<e[1][i-1])
    continue;
    if(i<m&&e[1][i]<e[1][i+1])
    continue;
    memset(l,0,sizeof(l));
    o(i,1,i);
    }
    for(i=1;i<=m;i++)
    if(w[i])
    x++;
    if(x<m)
    {
    cout<<"0\n"<<m-x;
    return 0;
    }
    sort(a+1,a+1+m);
    for(i=1;i<=m;i++)
    f[i]=0x7fffffff/2;
    for(i=1;i<=m;i++)
    {
    if(i<a[t].r)
    continue;
    while(t<=m&&i>a[t].r)
    t++;
    while(i==a[t].r)
    f[i]=min(f[i],f[a[t++].l-1]+1);
    for(j=1;j<i;j++)
    f[j]=min(f[j],f[i]);
    }
    cout<<"1\n"<<f[m];
    }

  • 0
    @ 2014-11-04 20:59:22

    const d:array[1..4,1..2]of shortint=((0,1),(0,-1),(-1,0),(1,0));
    var
    i,j,k,n,m,t,ans:longint;
    l,r:array[1..500]of longint;
    a:array[1..500,1..500]of longint;
    f:array[0..501,0..501]of boolean;
    procedure pre;
    var i:longint;
    begin
    fillchar(f,sizeof(f),0);
    for i:=1 to m do
    begin f[0,i]:=true; f[n+1,i]:=true end;
    for i:=1 to n do
    begin f[i,0]:=true; f[i,m+1]:=true end
    end;
    PROCEDURE qs(p,q:word);
    VAR
    i,j,k1,k2,t:longint;
    BEGIN
    i:=p; j:=q;
    k1:=l[(p+q)shr 1];
    k2:=r[(p+q)shr 1];
    REPEAT
    WHILE (l[i]<k1)or(l[i]=k1)and(r[i]>k2) DO inc(i);
    WHILE (l[j]>k1)or(l[j]=k1)and(r[j]<k2) DO dec(j);
    IF i<=j
    THEN BEGIN
    t:=l[i]; l[i]:=l[j]; l[j]:=t;
    t:=r[i]; r[i]:=r[j]; r[j]:=t;
    inc(i); dec(j)
    END;
    UNTIL i>j;
    IF j>p THEN qs(p,j);
    IF i<q THEN qs(i,q)
    END;
    procedure floodfill(x,y:integer);
    var
    i,nx,ny:integer;
    begin
    f[x,y]:=true;
    for i:=1 to 4 do
    begin
    nx:=x+d[i,1]; ny:=y+d[i,2];
    if not f[nx,ny]and(a[nx,ny]<a[x,y])
    then floodfill(nx,ny)
    end
    end;
    begin
    readln(n,m); pre;
    for i:=1 to n do
    for j:=1 to m do read(a[i,j]);
    if n>1 then
    begin
    for i:=1 to m do
    if not f[1,i] then floodfill(1,i);
    for i:=1 to m do
    if not f[n,i] then inc(k);
    if k>0 then
    begin writeln(0); write(k); exit end;
    pre
    end;
    for i:=1 to m do
    begin
    floodfill(1,i);
    for j:=1 to m+1 do
    if f[n,j] then break;
    if j<=m then l[i]:=j;
    for j:=m downto 0 do
    if f[n,j] then break;
    if j>0 then r[i]:=j; pre
    end;
    qs(1,m); i:=1; ans:=1; j:=0;
    while l[i]=0 do inc(i);
    repeat
    inc(j); l[j]:=l[i]; r[j]:=r[i];
    while l[i]=l[j] do inc(i);
    until i>m;
    t:=m; m:=j; i:=1;
    if r[i]<t then
    repeat
    j:=r[i]; n:=0;
    for i:=i+1 to m do
    begin
    if l[i]>j+1 then break;
    if r[i]>n then
    begin n:=r[i]; k:=i end
    end;
    i:=k; j:=n; inc(ans)
    until n=t;
    writeln(1); write(ans)
    end.

  • 0
    @ 2014-10-25 13:34:25

    NOIP2014赛前AC留念
    const x:array[1..4] of integer=(-1,1,0,0);
    y:array[1..4] of integer=(0,0,-1,1);

    var c:array[0..700,1..2] of longint;
    linex,liney:array[0..500000] of longint;
    h:array[0..700,0..700] of longint;
    n,m,nowx,j,nowy,temp,i,ans:longint;
    use:array[0..700,0..700] of boolean;
    f:array[0..701] of longint;

    function can(a,b:longint):boolean;
    begin
    if h[a,b]<h[nowx,nowy] then
    if (a>0) and (a<=n) and (b>0) and (b<=m) and (not use[a,b]) then
    exit(true);
    exit(false);
    end;

    procedure bfs;
    var opened,closed,i,j:longint;
    begin
    opened:=0;
    closed:=m;
    for i:=1 to m do
    begin
    linex[i]:=1;
    liney[i]:=i;
    use[1,i]:=true;
    end;
    repeat
    inc(opened);
    nowx:=linex[opened];
    nowy:=liney[opened];
    for i:=1 to 4 do
    begin
    if can(nowx+x[i],nowy+y[i]) then
    begin
    use[nowx+x[i],nowy+y[i]]:=true;
    inc(closed);
    linex[closed]:=nowx+x[i];
    liney[closed]:=nowy+y[i];
    end;
    end;
    until opened>=closed;
    for j:=1 to m do
    if not use[n,j] then inc(ans);
    end;

    function min(a,b:longint):longint;
    begin
    if a<b then exit(a)
    else exit(b);
    end;

    procedure dfs(k,p:longint);
    var i:longint;
    begin
    use[k,p]:=true;

    if k=n then
    begin
    if p>c[temp,2] then c[temp,2]:=p;
    if (p<c[temp,1]) or (c[temp,1]=0) then c[temp,1]:=p;
    end;

    for i:=1 to 4 do
    begin
    nowx:=k;
    nowy:=p;
    if can(k+x[i],p+y[i]) then
    begin

    dfs(k+x[i],p+y[i]);
    end;
    end;

    end;

    begin
    //assign(input,'flow.in');
    //assign(output,'flow.out');
    //reset(input);
    //rewrite(output);
    readln(n,m);
    for i:=1 to n do
    for j:=1 to m do read(h[i,j]);
    bfs;
    if ans>0 then
    begin
    writeln(0);
    writeln(ans);
    //close(input);
    //close(output);
    halt;
    end;

    for i:=1 to m do
    begin
    temp:=i;
    fillchar(use,sizeof(use),false);
    dfs(1,i);
    end;

    for i:=1 to m do
    begin
    f[i]:=maxlongint;
    for j:=1 to m do
    if c[j,2]>=i then
    if c[j,1]<=i then
    if f[c[j,1]-1]<>maxlongint then
    f[i]:=min(f[c[j,1]-1]+1,f[i]);
    end;

    writeln(1);
    writeln(f[m]);
    //close(input);
    //close(output);
    end.

  • 0
    @ 2014-08-04 12:38:55

    windows下DFS过不了第三个TAT

  • 0
    @ 2014-07-31 22:57:51

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #define INF (~0U>>4)
    using namespace std;
    int n,m;
    int h[502][502];
    int f[502];
    bool arr[502];
    struct Q
    {
    int x,y;
    }q[1000006];
    int ll[502][502],rr[502][502];
    int ans1=0;
    bool vst[502][502];
    const int px[4]={0,1,0,-1},py[4]={1,0,-1,0};
    bool Check(int x,int y)
    {
    if (x<0 || y<0) return false;
    if (x>n || y>m) return false;
    if (vst[x][y]) return false;
    return true;
    }
    void Bfs(int u)
    {
    int l=0,r=0;
    q[++r].x=1,q[r].y=u;
    vst[1][u]=true;
    while (l!=r)
    {
    ++l;
    l%=1000006;
    Q x=q[l];
    for (int i=0;i<4;i++)
    if (Check(x.x+px[i],x.y+py[i]) && h[x.x][x.y]>h[x.x+px[i]][x.y+py[i]])
    {
    vst[x.x+px[i]][x.y+py[i]]=true;
    ++r,r%=1000006;
    q[r].x=x.x+px[i],q[r].y=x.y+py[i];
    }
    }
    }
    void Bfs1(int u)
    {
    int l=0,r=0;
    q[++r].x=n,q[r].y=u;
    vst[n][u]=true;
    ll[n][u]=u;
    while (l!=r)
    {
    ++l;
    l%=1000006;
    Q x=q[l];
    for (int i=0;i<4;i++)
    if (Check(x.x+px[i],x.y+py[i]) && h[x.x][x.y]<h[x.x+px[i]][x.y+py[i]])
    {
    vst[x.x+px[i]][x.y+py[i]]=true;
    ll[x.x+px[i]][x.y+py[i]]=u;
    ++r,r%=1000006;
    q[r].x=x.x+px[i],q[r].y=x.y+py[i];
    }
    }
    }
    void Bfs2(int u)
    {
    int l=0,r=0;
    q[++r].x=n,q[r].y=u;
    vst[n][u]=true;
    rr[n][u]=u;
    while (l!=r)
    {
    ++l;
    l%=1000006;
    Q x=q[l];
    for (int i=0;i<4;i++)
    if (Check(x.x+px[i],x.y+py[i]) && h[x.x][x.y]<h[x.x+px[i]][x.y+py[i]])
    {
    vst[x.x+px[i]][x.y+py[i]]=true;
    rr[x.x+px[i]][x.y+py[i]]=u;
    ++r,r%=1000006;
    q[r].x=x.x+px[i],q[r].y=x.y+py[i];
    }
    }

    }
    int main()
    {
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    for (int j=1;j<=m;j++) scanf("%d",h[i]+j);
    for (int i=1;i<=m;i++) if (!vst[1][i])Bfs(i);
    int x=0;
    for (int i=1;i<=m;i++)
    x+=vst[n][i];
    if (x!=m)
    {
    puts("0");
    printf("%d\n",m-x);
    return 0;
    }
    memset(vst,0,sizeof(vst));
    for (int i=1;i<=m;i++)
    if (!vst[n][i])Bfs1(i);
    memset(vst,0,sizeof(vst));
    for (int i=m;i;i--)
    if (!vst[n][i])Bfs2(i);
    for (int i=1;i<=m;i++)
    if (ll[1][i]) f[ll[1][i]]=max(f[ll[1][i]],rr[1][i]);
    int last=f[1],r=f[1];
    int ans=1;
    for (int i=1;i<=m && last<m;i++)
    {
    if (i>last) last=max(f[i],r),ans++;
    r=max(r,f[i]);
    }
    puts("1");
    printf("%d\n",ans);
    return 0;
    }

  • 0
    @ 2013-11-02 17:01:32

    速度还可以吧。。线段覆盖写了O(n log n)的。
    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 5900 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 5900 KiB, score = 10
    测试数据 #2: Accepted, time = 19 ms, mem = 5904 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 5904 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 5908 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 5916 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 5916 KiB, score = 10
    测试数据 #7: Accepted, time = 15 ms, mem = 5908 KiB, score = 10
    测试数据 #8: Accepted, time = 0 ms, mem = 5932 KiB, score = 10
    测试数据 #9: Accepted, time = 31 ms, mem = 5988 KiB, score = 10
    Accepted, time = 65 ms, mem = 5988 KiB, score = 100

    http://hi.baidu.com/greencloud/item/939e36ce914e5726ef466562

  • 0
    @ 2013-10-28 20:45:19

    O(n^2)算法,先dfs判断可行,然后再dfs求出每个临湖城市能覆盖的区间,最后DP求解,三步均为n^2。对于pascal来说还算是漂亮的时间:

    编译成功

    测试数据 #0: Accepted, time = 0 ms, mem = 6144 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 6148 KiB, score = 10
    测试数据 #2: Accepted, time = 62 ms, mem = 6144 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 6152 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 6148 KiB, score = 10
    测试数据 #5: Accepted, time = 15 ms, mem = 6144 KiB, score = 10
    测试数据 #6: Accepted, time = 15 ms, mem = 6148 KiB, score = 10
    测试数据 #7: Accepted, time = 15 ms, mem = 6144 KiB, score = 10
    测试数据 #8: Accepted, time = 15 ms, mem = 6148 KiB, score = 10
    测试数据 #9: Accepted, time = 93 ms, mem = 6160 KiB, score = 10
    Accepted, time = 215 ms, mem = 6160 KiB, score = 100

    uses math;
    type
    rec=record
    x,y:longint;
    end;
    var
    n,m,i,j,top,ans:longint;
    ok:array[0..501,0..501]of boolean;
    a:array[0..501,0..501]of longint;
    ll,rr:array[0..501,0..501]of longint;
    st:array[0..250000]of rec;
    f:Array[0..501]of longint;

    procedure check(x,y,i,j:longint);
    begin
    if (i<1)or(i>n)or(j<1)or(j>m) then exit;
    if a[x,y]<=a[i,j] then exit;
    if ok[i,j] then exit;
    inc(top); ok[i,j]:=true;
    st[top].x:=i; st[top].y:=j;
    end;
    procedure dfs(x,y:longint);
    begin
    st[1].x:=x; st[1].y:=y; top:=1; ok[x,y]:=true;
    while top>0 do
    begin
    x:=st[top].x; y:=st[top].y; dec(top);
    check(x,y,x,y-1); check(x,y,x,y+1);
    check(x,y,x-1,y); check(x,y,x+1,y);
    end;
    end;

    function check2(x,y,i,j:longint):boolean;
    begin
    if (i<1)or(i>n)or(j<1)or(j>m) then exit(false);
    if a[x,y]<=a[i,j] then exit(false);
    exit(true);
    end;
    procedure dfs2(x,y:longint);
    begin
    if ok[x,y] then exit;
    ok[x,y]:=true;
    if check2(x,y,x,y-1) then begin
    dfs2(x,y-1);
    ll[x,y]:=min(ll[x,y],ll[x,y-1]);
    rr[x,y]:=max(rr[x,y],rr[x,y-1]);
    end;
    if check2(x,y,x,y+1) then begin
    dfs2(x,y+1);
    ll[x,y]:=min(ll[x,y],ll[x,y+1]);
    rr[x,y]:=max(rr[x,y],rr[x,y+1]);
    end;
    if check2(x,y,x-1,y) then begin
    dfs2(x-1,y);
    ll[x,y]:=min(ll[x,y],ll[x-1,y]);
    rr[x,y]:=max(rr[x,y],rr[x-1,y]);
    end;
    if check2(x,y,x+1,y) then begin
    dfs2(x+1,y);
    ll[x,y]:=min(ll[x,y],ll[x+1,y]);
    rr[x,y]:=max(rr[x,y],rr[x+1,y]);
    end;
    end;

    begin
    readln(n,m);
    for i:=1 to n do
    for j:=1 to m do
    read(a[i,j]);
    fillchar(ok,sizeof(ok),false);
    for j:=1 to m do
    if not ok[1,j] then dfs(1,j);
    ans:=0;
    for j:=1 to m do
    if not ok[n,j] then inc(ans);
    if ans>0 then begin writeln(0); writeln(ans); halt; end;
    fillchar(ll,sizeof(ll),127);
    fillchar(rr,sizeof(rr),0);
    for i:=1 to m do begin ll[n,i]:=i; rr[n,i]:=i; end;
    fillchar(ok,sizeof(ok),false);
    for i:=1 to m do
    if not ok[1,i] then dfs2(1,i);
    fillchar(f,sizeof(f),127);
    f[0]:=0;
    for i:=1 to m do
    for j:=ll[1,i]-1 to rr[1,i]-1 do
    f[rr[1,i]]:=min(f[rr[1,i]],f[j]+1);
    writeln(1);
    writeln(f[m]);
    end.

    就是代码略长……

信息

ID
1777
难度
7
分类
动态规划 点击显示
标签
递交数
2974
已通过
565
通过率
19%
被复制
10
上传者