http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41044#overview
补题顺序、F--G--C--D--E--I
F : 这题挺好想的,但是左右方向那个地方有点困难,我借鉴了男的方法,感觉很巧妙。
有两点注意:1.这题又是坑爹的行列不按顺序给出,2.我WA了一次。貌似是队列数组什么的没有清零。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int,int> pii;
const int dx[4]={0,-1,0,1};
const int dy[4]={-1,0,1,0};
int n,m;
int stx,sty;
char g[42][42];
queue<pii> q;
int vis[42][42];
int pace[42][42];
int check(int x,int y)
{
return (x>=0&&x<n&&y>=0&&y<m&&g[x][y]!='#');
}
int dfs_left(int x,int y)
{
int face=0;
int sum=0;
while (g[x][y]!='E') {
sum++;
for (int i=-1;i<3;i++) {
int tmp=(face+i+4)%4;
if (check(x+dx[tmp],y+dy[tmp])) {
face=tmp;
x=x+dx[tmp];
y=y+dy[tmp];
break;
}
}
}
return sum+1;
}
int dfs_right(int x,int y)
{
int sum=0,face=0;
while (g[x][y]!='E') {
sum++;
for (int i=1;i>-3;i--) {
int tmp=(face+i+4)%4;
if (check(x+dx[tmp],y+dy[tmp])) {
face=tmp;
x=x+dx[tmp];
y=y+dy[tmp];
break;
}
}
}
return sum+1;
}
int bfs(int stx,int sty)
{
memset(pace,0,sizeof(pace));
memset(vis,0,sizeof(vis));
if (!q.empty()) q.pop();
q.push(make_pair(stx,sty));
pace[stx][sty]=1;
vis[stx][sty]=1;
while (!q.empty()) {
pii tmp=q.front();
q.pop();
for (int i=0;i<4;i++) {
int x=tmp.first+dx[i];
int y=tmp.second+dy[i];
if (check(x,y)&&vis[x][y]==0) {
q.push(make_pair(x,y));
pace[x][y]=pace[tmp.first][tmp.second]+1;
vis[x][y]=1;
if (g[x][y]=='E') {
return pace[x][y];
}
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while (T--) {
scanf("%d%d",&m,&n);
for (int i=0;i<n;i++) {
scanf("%s",g[i]);
for (int j=0;j<m;j++)
if (g[i][j]=='S') {
stx=i;
sty=j;
}
}
printf("%d ",dfs_left(stx,sty));
printf("%d ",dfs_right(stx,sty));
printf("%d\n",bfs(stx,sty));
}
return 0;
}
G: 这题是个深搜啊。一开始没想到。看到求最小值,以为是bfs。 额。知道是深搜之后,难度就不是很大了,但是也调了好久。囧、
这题男四个方向单独写的,我是做了一个循环,代码简洁了许多。哈哈。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
int n,m;
int g[22][22];
int ans;
int sum=0;
int stx,sty,glx,gly;
int check(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<m;
}
void dfs(int sum,int x,int y)
{
if (x==glx&&y==gly) {
if (ans==-1) ans=sum;
else ans=min(ans,sum);
return;
}
if (sum==10) return;
for (int dir=0;dir<4;dir++) {
int tx=x,ty=y;
while (check(tx,ty)&&g[tx][ty]==0) {
if (tx==glx&&ty==gly) {
if (ans==-1) ans=sum+1;
else ans=min(ans,sum+1);
return;
}
tx+=dx[dir];
ty+=dy[dir];
}
if (check(tx,ty)&&g[x+dx[dir]][y+dy[dir]]==0) {
g[tx][ty]=0;
dfs(sum+1,tx-dx[dir],ty-dy[dir]);
g[tx][ty]=1;
}
}
}
int main()
{
while (~scanf("%d%d",&m,&n)&&n&&m) {
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
scanf("%d",&g[i][j]);
if (g[i][j]==2) {
stx=i;
sty=j;
g[i][j]=0;
}
if (g[i][j]==3) {
glx=i;
gly=j;
g[i][j]=0;
}
}
}
ans=-1;
dfs(0,stx,sty);
cout<<ans<<endl;
}
}
C:还没有调好。。。现在是2014年2月25日00:44:10。。所以还是睡觉吧。不过我把D先做好了。
D : 这题编程难度不大,主要是思路有点离奇,反正我是没有想到。。
#include <queue>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn = 120000;
int a[maxn];
queue<int> q;
vector<int> ans;
vector<int> edge[maxn];
int main(){
int i, j, n, m;
scanf("%d%d",&n,&m);
for(i = 0; i < m; i++){
int u, v;
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
}
for(i = 1; i <= n; i++){
scanf("%d",&a[i]);
if(a[i] == 0)
q.push(i);
}
while(!q.empty()){
int now = q.front();
q.pop();
ans.push_back(now);
for(i = 0; i < (int)edge[now].size();i++){
int next = edge[now][i];
--a[next];
if(a[next] == 0)
q.push(next);
}
}
printf("%d\n",ans.size());
for(i = 0; i < (int)ans.size();i++)
if(i == (int)ans.size()-1)
printf("%d\n",ans[i]);
else
printf("%d ",ans[i]);
return 0;
}