week4CSP模拟测试——BFS、DFS

主要思路:

一道BFS、DFS题
简单分析本题的测试数据可以得到,如果不剪枝,必然超时(毕竟2n 复杂度),所以关键在剪枝,找出那些后续无需进行的“点”;我们不能仅仅靠横纵坐标判断是否到达同一个点,因为对于再次到达的一点来说,有可能方向不同了或者前行的长度不同了,所以以上的情况都是不能剪掉的。
综上所述,同一个“点”的要求如下:

  • 横纵坐标相同
  • 当前的朝向相同
  • 当前分裂的次数相同

显然我们需要一个四维的数组来记录其状态(或者看作是四维空间的一个点),vis[x][y][level][direction]用来记录

B - 咕咕东想吃饭

众所周知,瑞神已经达到了CS本科生的天花板,但殊不知天外有天,
人外有苟,在浩瀚的宇宙中,存在着一种叫做苟狗的生物,
这种生物天生就能达到人类研究生的知识水平,并且天生擅长CSP,
甚至有全国第一的水平!但最可怕的是,它可以发出宇宙射线!
宇宙射线可以摧毁人的智商,进行降智打击!
宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),
初始方向默认向上。宇宙射线会在发射出一段距离后分裂,
向该方向的左右45°方向分裂出两条宇宙射线,同时威力不变!
宇宙射线会分裂 次,每次分裂后会在分裂方向前进 个单位长度。
现在瑞神要带着他的小弟们挑战苟狗,
但是瑞神不想让自己的智商降到普通本科生 那么菜的水平,
所以瑞神来请求你帮他计算出共有多少个位置会被"降智打击

在这里插入图片描述
Input

输入第一行包含一个正整数n,表示宇宙射线会分裂n次
第二行包含n个正整数 
第ai个数表示第ai次分裂的宇宙射线会在它原方向上继续走多少个单位长度。

Output

输出一个数 ,表示有多少个位置会被降智打击

Sample Input

4
4 2 2 3

Sample Output

39

A Possible Solution

#include<iostream>
#include<string.h>
#include<set>
using namespace std;

typedef struct tagPoint{
	int x,y;
	
	tagPoint(int X,int Y){
		x=X;
		y=Y;
	}
	
	bool operator < (const tagPoint& p) const {
		if(x==p.x)return y<p.y;
		return x<p.x;
	}
}Point;

set<Point> s;
bool vis[306][306][8][31];
int n,arr[31],
	dx[]={0,1,1,1,0,-1,-1,-1},
	dy[]={1,1,0,-1,-1,-1,0,1};

void solve(int x,int y,int level,int dir){
	if(level==n)
		return ;
	if(vis[x][y][dir][level])
		return ;
	
	if(level)
		vis[x][y][dir][level]=true;
	
//	cout<<"original : "<<x<<"   "<<y<<endl; 
	for(int i=1;i<=arr[level];i++){
		s.insert({x+i*dx[dir],y+i*dy[dir]});
//		cout<<x+i*dx[dir]<<"  "<<y+i*dy[dir]<<endl;
	}
//	cout<<endl;
	
	int dir1=dir-1,dir2=dir+1;
	if(dir1==-1)dir1=7;
	if(dir2==8)dir2=0;
	
	solve(x+dx[dir]*arr[level],y+dy[dir]*arr[level],level+1,dir1);
	solve(x+dx[dir]*arr[level],y+dy[dir]*arr[level],level+1,dir2);
}

int main(){
	memset(vis,0,sizeof(vis));
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>arr[i];
	solve(152,152,0,0);
	cout<<s.size()<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值