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