zoukankan      html  css  js  c++  java
  • codeforce 192 div2解题报告

    今天大家一起做的div2,怎么说呢,前三题有点坑,好多特判....

    A. Cakeminator

    题目的意思是说,让你吃掉cake,并且是一行或者一列下去,但是必须没有草莓的存在。这道题目,就是判断一下每行和每列的情况,看是不是有草莓存在,有的话就标记一下。后面就直接把木有草莓的行和列求和再减去重复路过的cake就行,不过你第一遍写的比较麻烦,小数据过了,后来WA了,现在改了一种写法。就是简单的加加减减。上代码:

     

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <string.h>
    #include <map>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    int n, m;
    char sp[200][200];
    int x[200];
    int y[200];
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i< n; ++i)
            scanf("%s", sp[i]);
        memset(x, 0, sizeof(x));
        memset(y, 0, sizeof(y));
        int sumxs = 0, sumys = 0;
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < m; ++j)
            {
                if(sp[i][j] == 'S')
                {
                    x[i] = 1;
                    sumxs++;
                    break;
                }
            }
        }
        for(int i = 0; i < m; ++i)
            for(int j = 0; j <n; ++j)
            {
                if(sp[j][i] == 'S')
                {
                    y[j] =1;
                    sumys++;
                    break;
                }
            }
        //cout << sumxs << ' ' << sumys <<endl;
        int cnt = 0;
        cnt += (n-sumxs)*m;
        cnt += (m-sumys)*n;
        //cout << cnt <<endl;
        cnt -= ((n-sumxs)*(m-sumys));
        cout << cnt <<endl;
        return 0;
    }


    B. Road Construction

    题目的意思是说现在给你n个点,然后在给你m个关系,这m个个关系表示某两条边之间不能连边,问你求最短的建筑方案是什么,要求任意两点之间距离不能超过2.

    这道题目当时纠结了很久,不知道怎么去链接,后面才想到这只能是所有的点围在一个点的周围的情况。其它的总会有两点之间的距离超过2的。所以就简单了,直接找到可以和任何一个点相连的点,输出他和剩下的点的序列就行了 。

     

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <string.h>
    #include <map>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    char sp[200][200];
    int main()
    {
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; ++i)
            scanf("%s", sp[i]);
        int hang = 0;
        int sum[10000];
        int k = 0;
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                if(sp[i][j] == '.')
                {
                    //cout << i << ' ' << j <<endl;
                    hang++;
                    sum[k++] = i+1;
                    sum[k++] = j+1;
                    break;
                }
            }
        }
        if(hang == n)
        {
            for(int i = 0; i < k-1; i+=2)
                printf("%d %d
    ", sum[i], sum[i+1]);
        }
        else
        {
            int lie = 0;
            k = 0;
            for(int i = 0; i < n; ++i)
            {
                for(int j = 0; j < n; ++j)
                {
                    if(sp[j][i] == '.')
                    {
                        //cout << i << ' ' << j <<endl;
                        lie++;
                        sum[k++] = j+1;
                        sum[k++] = i+1;
                        break;
                    }
                }
            }
            if(lie < n)
                printf("-1
    ");
            else
            {
                for(int i = 0; i < k-1; i+=2)
                    printf("%d %d
    ", sum[i], sum[i+1]);
            }
        }
    
        return 0;
    }


    C. Purification

    题目的意思是说,你面对一个方格,这个方格的,每一个点都需要“清洗”一下。但是有的点是可以站立的,有些点是僵尸,不能站立。你的能力是当你站在一个点上时,你可以“清洗”你所在的行和列。现在给你当前方格的状态,求出最小的站立点数,使得所有的点都能被“清洗”掉。

    就是把每一行和每一列“覆盖”一下啊。站就行了。从行开始检测,如果每一行都可以站立,那就OK了。不能的话就在从列开始检测,如果可以就OK,还是不行的话就输出“-1”就可以了。最少的步数不是行数/列数就是-1了,OK,判断:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <string.h>
    #include <map>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    char sp[200][200];
    int main()
    {
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; ++i)
            scanf("%s", sp[i]);
        int hang = 0;
        int sum[10000];
        int k = 0;
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                if(sp[i][j] == '.')
                {
                    //cout << i << ' ' << j <<endl;
                    hang++;
                    sum[k++] = i+1;
                    sum[k++] = j+1;
                    break;
                }
            }
        }
        if(hang == n)
        {
            for(int i = 0; i < k-1; i+=2)
                printf("%d %d
    ", sum[i], sum[i+1]);
        }
        else
        {
            int lie = 0;
            k = 0;
            for(int i = 0; i < n; ++i)
            {
                for(int j = 0; j < n; ++j)
                {
                    if(sp[j][i] == '.')
                    {
                        //cout << i << ' ' << j <<endl;
                        lie++;
                        sum[k++] = j+1;
                        sum[k++] = i+1;
                        break;
                    }
                }
            }
            if(lie < n)
                printf("-1
    ");
            else
            {
                for(int i = 0; i < k-1; i+=2)
                    printf("%d %d
    ", sum[i], sum[i+1]);
            }
        }
    
        return 0;
    }


    D. Biridian Forest

    题目的意思就是打怪,你站在S点,要前往E点,但是森林中存在怪物,他们也会移动,并且移动的速度和你的一样。你如果到达一个点,这个点也有怪物的话,那你就需要大战怪兽,大战的次数等于怪物的数量。问你最少的大战次数是多少。

    由于要求最优路径,肯定要用到BFS,再者,我们需要考虑如何计算我们会不会和怪兽碰上。按照题目意思,只要我们到出口的距离大于怪兽的点到出口的距离,那么我们就会碰到怪兽,这样的话,就直接可以从出口开始,求出各个点到出口的最短距离,再把怪兽的距离和我们的S的距离进行比较,如果小于的话那就不可避免的大战了,额,好吧。就是这样了:

     

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <string.h>
    #include <map>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    char sp[1500][1500];
    struct node
    {
        int x;
        int y;
    } st,ed;
    int vis[1500][1500];
    int n, m;
    int dx[4] = {0, 0, -1, 1};
    int dy[5] = {-1, 1, 0, 0};
    bool inmap(node a)
    {
        if(a.x <0||a.x >= n || a.y<0 || a.y >=m)
            return false;
        return true;
    }
    
    void BFS()
    {
        memset(vis, -1, sizeof(vis));
        queue<node>Q;
        vis[ed.x][ed.y] = 0;
        Q.push(ed);
        node next;
        while(!Q.empty())
        {
            node tp = Q.front();
            Q.pop();
            for(int i = 0; i < 4; ++i)
            {
                next.x = tp.x+dx[i];
                next.y = tp.y+dy[i];
                if(inmap(next) && vis[next.x][next.y]==-1&&sp[next.x][next.y]!='T')
                {
                    vis[next.x][next.y] = vis[tp.x][tp.y]+1;
                    Q.push(next);
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i)
            scanf("%s", sp[i]);
        int flag = 0;
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < m; ++j)
            {
                if(sp[i][j] == 'S')
                {
                    st.x = i;
                    st.y = j;
                    if(flag == 1)
                    {
                        i = n;
                        j = m;
                    }
                    else
                        flag = 1;
                }
                if(sp[i][j] == 'E')
                {
                    ed.x = i;
                    ed.y = j;
                    if(flag == 1)
                    {
                        i = n;
                        j = m;
                    }
                    else
                        flag = 1;
                }
            }
        }
        BFS();
        int cnt = 0;
        int MAX = vis[st.x][st.y];
        for(int i = 0; i <n ; ++i)
        {
            for(int j = 0; j < m; ++j)
            {
                if(sp[i][j]>='1'&& sp[i][j]<='9')
                    if(vis[i][j] <= MAX && vis[i][j] != -1)
                        cnt+=(sp[i][j] - '0');
            }
        }
        cout << cnt <<endl;
        return 0;
    }
    


    E题,还在看...

  • 相关阅读:
    第三周作业
    第二周作业
    第一周作业附加
    第三次结构部分作业
    第二次作业
    最后一周作业
    第14,15周作业
    第七周作业
    第六周作业
    第四周作业
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3206672.html
Copyright © 2011-2022 走看看