2014年2月23日小练习的补题、

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值