Codeforces Round #192 (Div. 2) 解题报告 //缺E
---------------
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; }---------------
---------------