现在的位置: 首页 > 综合 > 正文

CF 192

2019年02月09日 ⁄ 综合 ⁄ 共 3107字 ⁄ 字号 评论关闭

A题:给你一个图,里面有坏草莓,让你吃蛋糕,不能吃坏草莓所在的行和列,问你最多能吃多少块蛋糕。

这题感觉还是贪心的做法吧,根据题目给的图,先从行开始,把没有草莓的行都吃掉,然后从列开始,把没有草莓的列吃掉。

代码:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<cstdio>
#include<cstring>
#define maxn 2005
#define INF 0xfffffff
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std;
int r[20],col[20];
int main()
{
    int n,m;
    char s[20];
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        for(int j=0;j<m;j++)
        {
            if(s[j]=='S')
            {
                r[i]=1;
                col[j+1]=1;
            }
        }
    }
    int sum=0;
    int allr=0;
    for(int i=1;i<=n;i++)
    {
        if(r[i]==0)
        {
            sum+=m;
            allr++;
        }
    }
    for(int j=1;j<=m;j++)
    {
        if(col[j]==0)
        {
            sum+=(n-allr);
        }
    }
    cout<<sum<<endl;
	return 0;
}

B题:给你点和不能连的边,问你连最少的边,使任意一个点到其他点的距离都小于等于2。

把一个点连到其他所有的点就行了,开始还以为要用并查集,暴搜什么的,唉~~~水了。

代码:

#include<iostream>
#include<cstring>
#define maxn 1005
#define INF 0xfffffff
using namespace std;
int map[maxn][maxn];
int vis[maxn];
int main()
{
    int n,m,a,b,i,j;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        vis[a]=vis[b]=1;
    }
    for( i=1;i<=n;i++)
    {
        if(vis[i]==0)
        break;
    }
    cout<<n-1<<endl;
    for( j=1;j<=n;j++)
    {
        if(i!=j)
        cout<<i<<' '<<j<<endl;
    }
    return 0;
}

C题:给你一个图,一些点不能涂色,没涂一个点,它的上下左右四个方向都可以被涂色。

直接从每行,每列开始搜,如果存在某个点所在的行和列都没有可以涂色的位置,则输出-1。

然后分别行优先开始涂,列优先开始涂,求最小值。

代码:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<cstdio>
#include<cstring>
#define maxn 105
#define INF 0xfffffff
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std;
int r[maxn],c[maxn];
char a[maxn][maxn];
int main()
{
    int n;
    cin>>n;
    int flag1=0;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='.')
            {
                r[i]++;
                c[j]++;
            }
        }
    }
    int flag=0;
    for(int i=1; i<=n; i++)
    {
        if(r[i]==0)
            flag1=1;
        for(int j=1; j<=n; j++)
        {
            if(r[i]==0&&c[j]==0)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
            break;
    }
    if(flag==1)
    {
        cout<<-1<<endl;
        return 0;
    }
    int count=0;
    if(flag1==0)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(a[i][j]=='.')
                {
                    cout<<i<<' '<<j<<endl;
                    count++;
                    break;
                }
            }
        }
    }
    else
    {
        for(int j=1;j<=n;j++)
        {
            for(int i=1;i<=n;i++)
            {
                if(a[i][j]=='.')
                {
                    cout<<i<<' '<<j<<endl;
                    break;
                }
            }
        }
    }
    return 0;
}

D题:给你一个图,一个人想走到出口,其他人想阻拦他,问你这个人要和多少个人打架。

从出口开始bfs,在出口到先走到出口的人最短距离之内的所有人都要和他打架。

代码:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cstdio>
#include<cstring>
#define maxn 1005
#define INF 0xfffffff
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
using namespace std;
char map[maxn][maxn];
bool vis[maxn][maxn];
int n,m,sum,count;
int X[]={-1,1,0,0};
int Y[]={0,0,-1,1};
struct node
{
    int x,y,step;
};
bool inmap(int x,int y)
{
    if(0<=x&&x<n&&0<=y&&y<m)
    return true;
    else
    return false;
}
void bfs(int sx,int sy)
{
    queue<node>q;
    node s;s.x=sx,s.y=sy,s.step=0;
    node tmp;
    q.push(s);
    vis[sx][sy]=1;
    while(!q.empty())
    {
        tmp=q.front(),q.pop();
        int tx=tmp.x,ty=tmp.y,ts=tmp.step;
        if(map[tx][ty]=='S')
        {
            count=tmp.step;
        }
        //cout<<tx<<' '<<ty<<' '<<tmp.step<<' '<<count<<endl;
        if(tmp.step<=count&&map[tx][ty]!='E'&&map[tx][ty]!='S')
        {
            //cout<<tx<<' '<<ty<<' '<<map[tx][ty]<<endl;
            sum+=(int)(map[tx][ty]-'0');
        }
        for(int i=0;i<4;i++)
        {
            int nx=tx+X[i],ny=ty+Y[i];
            if(inmap(nx,ny)&&vis[nx][ny]==0&&map[nx][ny]!='T')
            {
                vis[nx][ny]=1;
                tmp.x=nx,tmp.y=ny,tmp.step=ts+1;
                if(tmp.step<=count)
                q.push(tmp);
            }
        }
    }
}
int main()
{
    int i,j,sx,sy;
    scanf("%d%d",&n,&m);
    for( i=0;i<n;i++)
    {
        scanf("%s",map[i]);
        for(j=0;j<m;j++)
        {
            if(map[i][j]=='E')
            {
                sx=i,sy=j;
            }
        }
    }
    count=INF;
    sum=0;
    bfs(sx,sy);
    printf("%d\n",sum);
    return 0;
}

E题:构造一个图,不含原图的边,并且新图边数与原图边数相同。

用随机数构造验证的方法,并设置构造次数。

【上篇】
【下篇】

抱歉!评论已关闭.