zoukankan      html  css  js  c++  java
  • 【Z10】引水入城

    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=z10

    【题解】

    对于第一问:从最上面那m个格子开始进行广搜就可以了;
    然后看一下最下面那一行有没有被全部覆盖;
    对于第二问:
    要先明确;从最上面的那m个格子中的任意一个点开始,在最下面的沙漠中行成的覆盖段一定是连续的一段;(有解的前提下);
    证明:
    假设最上面的格子x开始进行广搜在最下面形成了两段不连续的区间
    a..b c..d (b小于c)
    则必然在最上面的m个点中有一个点或多个点,能覆盖b..c这个区间;
    这里写图片描述
    但是如果那样覆盖的话,如上图所示,那个点(或多个点)在往下覆盖的时候肯定会和x往下覆盖的路径发生重叠,而既然那个点能往下走,为什么x号节点不能往下走?这就出现矛盾了;所以x格子不可能在最下面形成不连续的两段区间(或多段),则它只能形成一段连续的区间.
    则我们在判断完有解之后;
    再一个一个地以最上面那个湖泊的点为起点进行广搜,到最下面;看它能覆盖的区间是什么->求出m个区间;
    然后用这m个区间进行动规以求覆盖1..m所需要的最少区间数->区间数对应蓄水厂数目;
    f[i] = min(f[l[k]-1]+1,f[i]);其中r[k]>=i;

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int MAXN = 500+10;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n,m;
    int a[MAXN][MAXN];
    int flag[MAXN][MAXN];
    bool bo[MAXN][MAXN];
    int tag = 0;
    queue <pii> dl;
    
    void bfs()
    {
        while (!dl.empty())
        {
            int x = dl.front().fi,y = dl.front().se;
            dl.pop();
            rep1(k,1,4)
            {
                int tx = x+dx[k],ty = y+dy[k];
                if (bo[tx][ty])
                {
                    if (a[tx][ty]<a[x][y] && flag[tx][ty]!=tag)
                    {
                        flag[tx][ty] = tag;
                        dl.push(mp(tx,ty));
                    }
                }
            }
        }
    }
    
    int main()
    {
       // freopen("F:\rush.txt","r",stdin);
        memset(bo,false,sizeof(bo));
        rei(n);rei(m);
        rep1(i,1,n)
            rep1(j,1,m)
                rei(a[i][j]),bo[i][j] = true;
        memset(flag,0,sizeof(flag));
        tag++;
        rep1(i,1,m)
            {
                flag[1][i] = tag;
                dl.push(mp(1,i));
            }
        bfs();
        int cnt = 0;
        rep1(i,1,m)
            if (flag[n][i]==0)
                cnt++;
        if (cnt)
        {
            puts("0");
            printf("%d
    ",cnt);
            return 0;
        }
        else
        {
            vector <pii> a;
            rep1(i,1,m)
            {
                tag++;
                flag[1][i] = tag;
                dl.push(mp(1,i));
                bfs();
                pii temp;
                rep1(j,1,m)
                    if (flag[n][j]==tag)
                    {
                        temp.fi=j;
                        break;
                    }
                rep2(j,m,1)
                    if (flag[n][j]==tag)
                    {
                        temp.se = j;
                        break;
                    }
                a.pb(temp);
            }
            int f[MAXN],len = a.size();
            memset(f,0x3f3f3f3f,sizeof f);
            f[0] = 0;
            rep1(i,1,m)
                rep1(j,0,len-1)
                    if (a[j].se>=i)
                        f[i] = min(f[i],f[a[j].fi-1]+1);
            puts("1");
            printf("%d
    ",f[m]);
        }
        return 0;
    }
  • 相关阅读:
    【转】ListView,GridView之LayoutAnimation特殊动画的实现 ps:需要学习的是在getView中添加动画的思想
    自定义Dialog
    android 横向list特效——规格滑动
    android BaseAdapter优化
    自定义弧形进度条
    滑块闹钟界面
    HTML学习10
    HTML学习9
    HTML学习8
    HTML学习7
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626862.html
Copyright © 2011-2022 走看看