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;
}