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题:构造一个图,不含原图的边,并且新图边数与原图边数相同。
用随机数构造验证的方法,并设置构造次数。