zoukankan      html  css  js  c++  java
  • Codeforces Round #192 (Div. 2) 解题报告 //缺E

    ---------------

    A. Cakeminator

    rXc的蛋糕中有一些邪恶的草莓,如果某一行或某一列没有草莓我们可以吃掉这一排。

    问最多能吃多少蛋糕。

    ----

    直接暴力寻找空行空列即可。

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    const int maxn=21;
    
    char s[maxn][maxn];
    bool v[maxn][maxn];
    int r,c;
    
    int main()
    {
        memset(v,0,sizeof(v));
        cin>>r>>c;
        for (int i=1;i<=r;i++)
            cin>>(s[i]+1);
        for (int i=1;i<=r;i++)
        {
            bool flag=true;
            for (int k=1;k<=c;k++)
            {
                if (s[i][k]=='S')
                {
                    flag=false;
                    break;
                }
            }
            if (flag)
            {
                for (int k=1;k<=c;k++) v[i][k]=true;
            }
        }
        for (int j=1;j<=c;j++)
        {
            bool flag=true;
            for (int k=1;k<=r;k++)
            {
                if (s[k][j]=='S')
                {
                    flag=false;
                    break;
                }
            }
            if (flag)
            {
                for (int k=1;k<=r;k++) v[k][j]=true;
            }
        }
        int ans=0;
        for (int i=1;i<=r;i++)
        {
            for (int j=1;j<=c;j++)
            {
                if (v[i][j]) ans++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    ---------------

    B. Road Construction

    有n个城市,建造一些双向道路使任意一个城市到其他城市的路径不超过2。

    有m条路不能建造。求出一个可能的建造方案。

    ----

    观察发现,一个合理的方案是一棵只有叶子节点的深度为1的树。

    所以只要枚举根节点,判断是否能建造出所有的边即可。

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    const int maxn=1111;
    
    bool dis[maxn][maxn];
    int n,m;
    
    int main()
    {
        memset(dis,0,sizeof(dis));
        cin>>n>>m;
        for (int i=1;i<=m;i++)
        {
            int x,y;
            cin>>x>>y;
            dis[x][y]=true;
            dis[y][x]=true;
        }
        for (int rt=1;rt<=n;rt++)
        {
            bool flag=true;
            for (int i=1;i<=n;i++)
            {
                if (dis[rt][i])
                {
                    flag=false;
                    break;
                }
            }
            if (flag)
            {
                cout<<n-1<<endl;
                for (int i=1;i<=n;i++)
                {
                    if (i!=rt)
                    {
                        cout<<i<<" "<<rt<<endl;
                    }
                }
                break;
            }
        }
        return 0;
    }
    ---------------

    C. Purification

    在一个nXn的矩阵里有一些邪恶需要净化,每次选择一个点,该点所在的行和列包括自身都将被净化。

    有一些点不能被选择。要求选择的点最小。输出一种合理的选择方案。

    ----

    分析知,至少每一行都选择一个点,或每一列都选择一个点才能净化所有的格子。

    枚举每一行,选择一个能选择的点,存入答案序列中。

    如果有一行没有点可以选择,枚举每一列,选择一个能选择的点,存入序列。

    若有一列没有可以选择的点,则输出-1。

    若有解,则输出答案。

    #include <iostream>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    const int maxn=111;
    
    struct POINT{
        int x;
        int y;
        POINT(int a,int b):x(a),y(b){}
    };
    vector<POINT>ans;
    char s[maxn][maxn];
    int n;
    
    int main()
    {
        bool ok;
        bool flag;
        ans.clear();
        cin>>n;
        for (int i=1;i<=n;i++) cin>>(s[i]+1);
        //bool ret=dfs(1);
        flag=true;
        for (int i=1;i<=n;i++)
        {
            ok=false;
            for (int j=1;j<=n;j++)
            {
                if (s[i][j]=='.')
                {
                    ans.push_back(POINT(i,j));
                    ok=true;
                    break;
                }
            }
            if (!ok)
            {
                flag=false;
                break;
            }
        }
        if (!flag)
        {
            ans.clear();
            flag=true;
            for (int j=1;j<=n;j++)
            {
                ok=false;
                for (int i=1;i<=n;i++)
                {
                    if (s[i][j]=='.')
                    {
                        ans.push_back(POINT(i,j));
                        ok=true;
                        break;
                    }
                }
                if (!ok)
                {
                    flag=false;
                    break;
                }
            }
        }
        if (!flag) cout<<"-1"<<endl;
        else
        {
            //cout<<ans.size()<<endl;
            for (int i=0;i<ans.size();i++)
            {
                cout<<ans[i].x<<" "<<ans[i].y<<endl;
            }
        }
        return 0;
    }
    ---------------

    D. Biridian Forest
    在一个rXc的矩阵里有树、空地或数量在1-9之间的敌人。

    有一个门和一个起点,从起点出发找一条路径到终点。

    玩家和敌人每回合都能上下左右移动一个格子,回合结束后发生战斗。

    聪明的敌人会想办法与你相遇并发生战斗,问最小可能的战斗数。

    即使到达了终点也要与同时到达的敌人发生战斗。

    ----

    先找出一条路再判断是否能与敌人发生战斗必然是不可行的。

    可以发现,到达终点的时间小于等于玩家的敌人必然会发生战斗。(接近路径或者直接到终点守着-_-#)

    所以求出所有人到终点的距离再计算答案即可。

    即终点到所有人的距离。。。一次广搜解决。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    using namespace std;
    const int direct[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };
    const int INF=1e9+7;
    struct POINT{
        int x;
        int y;
        int dp;
        POINT(int a=0,int b=0,int c=0):x(a),y(b),dp(c){}
    };
    char s[1111][1111];
    int r,c,len;
    int ret;
    POINT door,start;
    
    bool check(POINT p)
    {
        if (p.x>=0&&p.x<r&&p.y>=0&&p.y<c) return true;
        return false;
    }
    vector<int>ans;
    vector<int>num;
    
    void bfs(POINT pin)
    {
        POINT p,tmp;
        bool vis[1111][1111];
        queue<POINT>que;
        memset(vis,0,sizeof(vis));
        while (!que.empty()) que.pop();
        pin.dp=0;
        que.push(pin);
        vis[pin.x][pin.y]=true;
        while (!que.empty())
        {
            tmp=que.front();
            que.pop();
            for (int i=0;i<4;i++)
            {
                p.x=tmp.x+direct[i][0];
                p.y=tmp.y+direct[i][1];
                p.dp=tmp.dp+1;
                if (check(p)&&!vis[p.x][p.y]&&s[p.x][p.y]!='T')
                {
                    vis[p.x][p.y]=true;
                    que.push(p);
                    if ( s[p.x][p.y]>='1'&&s[p.x][p.y]<='9' )
                    {
                        ans.push_back(p.dp);
                        num.push_back(s[p.x][p.y]-'0');
                    }
                    if ( s[p.x][p.y]=='S' ) len=p.dp;
                }
            }
        }
    }
    
    int main()
    {
        ans.clear();
        num.clear();
        ret=0;
        len=INF;
        cin>>r>>c;
        for (int i=0;i<r;i++) cin>>s[i];
        for (int i=0;i<r;i++)
        {
            for (int j=0;j<c;j++)
            {
                if (s[i][j]=='S')
                {
                    start.x=i;
                    start.y=j;
                    start.dp=0;
                }
                if (s[i][j]=='E')
                {
                    door.x=i;
                    door.y=j;
                    door.dp=0;
                }
            }
        }
        bfs(door);
        for (int i=0;i<ans.size();i++)
        {
            if (ans[i]<=len) ret+=num[i];
        }
        cout<<ret<<endl;
        return 0;
    }
    ---------------

    ---------------



  • 相关阅读:
    Matlab中的随机数生成器
    Matlab中的随机数生成器
    Matlab 函数返回矩阵
    Matlab 函数返回矩阵
    Matlab 函数返回矩阵
    矩阵同列同行复制原理
    矩阵同列同行复制原理
    Apache/RewriteRule
    使用google map v3添加经纬度信息
    评论:一站式学习C编程(升级版) (平装)
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226281.html
Copyright © 2011-2022 走看看