可怕的宇宙射线 Week4 CSPM1 C题

题目:

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

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

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

样例:
Input:
4
4 2 2 3

Output:
39

样例解释说明:
在这里插入图片描述

思路:

由题目简单计算可得,按最坏情况计算,射线传播范围也仅限于300*300的平面范围内,并不是很大。
所以,我们可以构造一张“图”,从中心开始发射,模拟分裂过程,最后遍历图确定覆盖区域。
使用类似于迷宫问题BFS解法的思想,从起点开始发射,在分裂过程中,对覆盖到的点进行标记,同时进行记忆化搜索,在相同位置、相同分裂情况下,要及时停止,从而降低复杂度。

代码:

#include <stdio.h>

int vis[330][330][35][8],//记录射线覆盖区域,表示(x,y)在第cnt次分裂,d方向延伸
    mp[330][330],a[35],
	n,ans;
int dir[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};//八个分裂方向 

void dfs(int x,int y,int cnt,int d){
	if(vis[x][y][cnt][d]) return;//已有相同情况覆盖,无需再次覆盖 
	vis[x][y][cnt][d]=1;//标记覆盖 
	for(int i=1;i<=a[cnt];i++){
		x+=dir[d][0], y+=dir[d][1];
		if(!mp[x][y]) ans++,mp[x][y]=1;//计数 
	}
	if(cnt<n) //继续分裂
	    dfs(x,y,cnt+1,(d+1)%8),dfs(x,y,cnt+1,(d+7)%8); 
} 

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	dfs(160,160,1,2);//从中心开始发射
	printf("%d\n",ans); 
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值