CF 192 DIV2

A. Cakeminator

题目链接

大水题,前提是要看懂题目

思路:记录一行都不存在草莓的行数s1,一列都不存在草莓的列数s2,然后求总格数,公式:s=s1*m+s2*n-s1*s2

代码:

#include <stdio.h>//192 div.2 A
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using  namespace std;
const int M=100010;
char a[15][15];
int vis[15][15];
int num;
int main()
{
    int n,m,i,j;
    memset(vis,0,sizeof(vis));
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
    scanf("%s",a[i]);
    int s=0;
    int s1=0,s2=0;
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            if(a[i][j]=='S')
            break;
        }
        if(j==m)
        {
            s+=m;
            s1++;
        }
    }
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            if(a[j][i]=='S')
            break;
        }
        if(j==n)
        {
            s+=n;
            s2++;
        }
    }
    s-=(s1*s2);
    printf("%d\n",s);
    return 0;
}

B. Road Construction

也很水呀,没看清题目,竟然想得复杂了~

注意两点:1.任意两点之间的长度不超过2  ,2.不能相连的边数m<n/2........赤裸裸的直接找空点,把其他点都连在那个点上

如果没有第一个条件有第二个条件,也可以证明存在这样一个点能和其他所有点相连

证明:一个无向图的的联通图最多共有(n-1)*n/2条边,而m<2/n; 由于n*(n-1)/2-(n/2)=(n/2)(n-1)>=n-1,而n个点相连至少需要n-1条边,非常满足。。。。。唉~仔细推想就不会觉得难了

代码:

#include <stdio.h>//192 div.2 B
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using  namespace std;
const int M=100010;
vector<int>p[M];
int vis[1001];
int f[1001][1001];
int s[1001];
int main()
{
    memset(f,0,sizeof(f));
    int n,m,i,a,b,j;
    cin>>n>>m;
    while(m--)
    {
        cin>>a>>b;
        f[a][b]=1;
        f[b][a]=1;
    }
    int si=1;
   // int gg=0;
    for(i=1; i<=n; i++)
    {
       int gg=0;
        for(j=1; j<=n; j++)
        {
            if(f[i][j]==1)
            {
                gg=1;
                break;
            }
        }
        if(gg==0)
        {
            si=i;
            break;
        }
    }
    cout<<n-1<<endl;
    for(i=1; i<=n; i++)
    {
        if(si!=i)
            cout<<si<<" "<<i<<endl;
    }
    return 0;
}

C. Purification

还是YY题呀,仔细想也是一水题

题意:放最少的炸弹把所有格子都炸掉,但放炸弹不能放在僵尸所在位置,求最少所需放炸弹的位置,不能全炸掉输出-1(当放一个炸弹就能把所在的行和列的所有格子炸掉)

思路:由题意可知,若要炸掉一个个点a(x,y),那么被炸掉的条件必须是要么是a所在的行至少有一个炸弹,要么是a所在的列至少有一个炸弹,否则不能炸掉。那么就可以推出,一个n*n的格子,要全部被炸掉,必须是要么所有的行都至少有一个炸弹,要么是所有的列至少有一个炸弹,所以放炸弹的位置至少是n....那么求最少也就是n个位置。。。

那么就很简单了

代码:

#include <stdio.h>//192 div.2 C
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using  namespace std;
const int M=100010;
char a[101][101];
int b[100002];
int vis[101][101];
int n;
int main()
{
    int i,j;
    memset(vis,0,sizeof(vis));
    scanf("%d",&n);
    for(i=1; i<=n; i++)
    {
        getchar();
        for(j=1; j<=n; j++)
            scanf("%c",&a[i][j]);
    }
    int l=0,k=0;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            if(a[i][j]=='.')
            {
                b[l++]=i;
                b[l++]=j;
                k++;
                break;
            }
        }
    }
    if(k==n)
    {
        for(int g=0; g<l; g+=2)
            cout<<b[g]<<" "<<b[g+1]<<endl;;
    }
    else
    {
        k=0,l=0;
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=n; j++)
            {
                if(a[j][i]=='.')
                {
                    b[l++]=j;
                    b[l++]=i;
                    k++;
                    break;
                }
            }
        }
        if(k==n)
        {
             for(int g=0; g<l; g+=2)
            cout<<b[g]<<" "<<b[g+1]<<endl;
        }
        else
        cout<<"-1"<<endl;
    }

    return 0;
}

D. Biridian Forest

稍微认真思考,就发现是一道简单的BFS搜索题,不过需要仔细推敲

题意:一个人从森林起点走到森林出口,期间不能走有树的地方,期间还会和别的生物打斗,和一只生物打算一场打斗,问从S-E这期间至少打斗几次

思路:把问题转化为人用最少的时间走到E点才能避免更多的打斗,因为与别人相遇的次数减少了,也就是求最短路径。。等等,那怎么求呢?  想象一下若这个人走的期间在某个格子和其他“人”打斗,所以那么从这个格子到E出口是需要一样时间的,我们可以把打斗的位置移到E出口位置,也就是想象成所有的打斗都在E出口位置进行,从而可以知道,若其他生物从它的位置到E出口的距离要小于等于人从S到E点的距离,生物才有可能在人到来之前等在E出口旁和人进行打斗!!!。。。


之前就想着所有生物到E出口的距离得要进行多少次BFS呀!后面换一个角度,从E到所有生物的距离!!!求吧,一次BFS就行


思路出来了,写代码就简单了

代码:

#include <stdio.h>//192 div.2 D
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
using  namespace std;
char a[1001][1001];
int step[1001][1001];
int dix[4]= {0,1,0,-1};
int diy[4]= {1,0,-1,0};
int n,m;
int ex,ey,sx,sy;
struct node
{
    int x,y;
} g[1001];
void bfs()
{
    queue<node>q;
    node cur,next;
    cur.x=ex;
    cur.y=ey;
    step[ex][ey]=0;
    q.push(cur);
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            next.x=cur.x+dix[i];
            next.y=cur.y+diy[i];
            if(next.x >=0 && next.x < n && next.y >= 0 && next.y < m)
            {
                if(a[next.x][next.y]!='T' && step[next.x][next.y]==-1)
                {
                    step[next.x][next.y]=step[cur.x][cur.y]+1;
                    q.push(next);
                }

            }
        }

    }
}
int main()
{
    memset(step,-1,sizeof(step));
    int i,j,s=0;
    scanf("%d%d",&n,&m);
    getchar();
    for(i=0; i<n; i++)
    {
        scanf("%s",a[i]);
    }
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
            if(a[i][j]=='S')
            {
                sx=i;
                sy=j;
                i=n;
                j=m;
            }
    }
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            if(a[i][j]=='E')
            {
                ex=i;
                ey=j;
                i=n;
                j=m;
            }
        }
    }
    bfs();
    int mmax=step[sx][sy];
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            if(a[i][j]>='1'&& a[i][j]<='9')
            {
                if(step[i][j]!=-1 && step[i][j]<=mmax)
                {
                    s+=(a[i][j]-'0');
                }
            }
        }
    }
    cout<<s<<endl;
    return 0;
}


代码
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值