[CSP-M1 C의 프로그래밍 생각과 실천] 끔찍한 우주선

주제 설명 :

우주선은 무한 이차원 평면 (이차원 격자 맵으로 간주 될 수있다) 디폴트의 초기 상 방향 전파. 우주선은 약 45이 방향의 거리 분할 후에 방출된다 . 동일의 힘 동안, 두 우주선을 분할! 우주선은 전방으로 분할 한 후, 분할마다 N 번 것이다 I의 길이 단위.

설명을 입력합니다 :

제 1 라인의 입력은 양의 정수 N (N <= 30) 우주선 Fenlie로 표시되는 N 번 포함
번째 줄에 포함 된 N의 정수하는 . 1 ,의` 2 , ...하는 N , I 다수의 I (A을 나는 <= 5) 내가 번째 우주선의 구분이 원래 방향으로 갈 것 길이 얼마나 많은 단위를 나타냅니다.

샘플 입력 :

4
4 2 2 3

출력 설명 :

숫자 ANS의 출력은, 여행 우주선의 단위 수를 나타냅니다.

샘플 출력 :

39

데이터 포인트 설명 :

데이터 포인트
10 % <= 10
40 % <= 20
100 % <= 30

아이디어 :

상기 판정을 반복하는 것은 많은 시간 복잡도를 가질 수있는 동안 어려움은 점이다. 불리언 두 평면을 나타내는, 불리언 값은 지점 통과했는지 여부에 의해 표시되며, 더 큰 배열을 만들 수있다. 때문에 I <= 5, N -. <= 30이므로 배열 300 * 300 정도의 크기를 가지고,이 사고 대금을 사용하여, 조금 크게 취할 수있는 각 발광 우주선 각 층 BFS 간주 할 확장, 즉, 각 대기열 후 노드를 사용하는 것은 다음의 방출의 연장 방향을 유지한다. 그러나이 방법 명백히 심한 BFS 타임 아웃, 따라서, 우리는 다섯 차원 어레이를 확립 한 의미의 각 치수는 Y 좌표 방향으로 길이 연장 된 여러 번, x 좌표이다. 따라서, 마커가 확산 한 지점에 사용할 수 있으며,이 점은 큐가 다시 같은 경로로 다시 갈 것이다 누르면 입력 된 경우 확장이 폐기 될 수 있도록 반복되면, 큐에 압입 할 기록이 없습니다 점, 우리는 크게 프로그램의 시간 복잡도를 감소시킬 수있다 그래서.

반사 :

1, 아니 이전 오의 배열을 사용하여 생각하지만, 네 차원 배열의 사용은 얼마나 많은 시간이 차원을 확장하지 않았지만, 시험 test7 실현 WA를 나타 났을 때, 그 어떤 5 차원, 이전 확장이없는 경우 촬영이 몇 점을 확장 할 수 있습니다 후,하고 포인트를 반복하기 전에 여러 번 확장 된 영향의 점의 제거 이후에 반복되지만, 그들은 단지이 단계 동일, 다음 확장은 다를 수 있습니다, 따라서 이러한 경우 중복 된 점을 제거하는 지점으로 의심 할 여지없이 케이스의 일부는 5 차원 배열의 따라서 사용, 분실 것, 또는 4 차원 배열은 확장 된 모든 마크의 다음 층 전에 제로 쓸 수 있습니다.
도 2는, 다시 태그에 각 계층 확장해야하므로, 각 층은 매우 약간 중복 다섯 차원 어레이의 길이 치수에 제거 될 수있는, 그 송신 길이의 동일한 확장 점이다.
도 3에서, 분할의 방향을 결정하기 위해, 판사 긴 switch 문을 작성하지만, 나중에 좌우 방향으로 원 (45)의 방향으로 각각의 분할 이후의 패턴은,이 각 분할 후 방향 변경 발견 . 만약 원래 방향 어레이로 기록 후의 시계 방향의 반대 방향으로 분할 원래 방향의 방향 및 + + 1mod8 7mod8. 이 방향의 결정을 단순화시킨다.

코드 :

#include <iostream>
#include <string.h>
#include <queue>
#include <vector>
using namespace std;
struct Point{
	int x;
	int y;
	Point(int thex,int they)
	{
		x=thex,y=they;
	}
};
bool vis[400][400];
bool note[400][400][8][6][30];
queue<pair<Point,int>> qq;
int dx[]={0,-1,-1,-1,0,1,1,1};
int dy[]={1,1,0,-1,-1,-1,0,1};
int main(int argc, char** argv) {
	memset(vis,false,400*400*sizeof(bool));
	memset(note,false,400*400*8*6*30*sizeof(bool));
	int n;
	cin>>n;
	Point now(199,199);
	vector<int> length(n+1);
	for(int i=0;i<n;i++)
		cin>>length[i];
	int count=0,number=1;
	qq.push({now,0});
	note[now.x][now.y][0][length[0]][0]=true;
	for(int i=0;i<n;i++)
	{
		int num=0;
		for(int j=0;j<number;j++)
		{
			now=qq.front().first;
			int forword=qq.front().second;
			qq.pop();
			for(int k=0;k<length[i];k++)
			{
				now.x+=dx[forword];
				now.y+=dy[forword];
				if(!vis[now.x][now.y])
				{
					vis[now.x][now.y]=true;
					count++;
				}
			}
			if(!note[now.x][now.y][(forword+1)%8][length[i+1]][i])
			{
				note[now.x][now.y][(forword+1)%8][length[i+1]][i]=true;
				qq.push({now,(forword+1)%8});
				num++;
			}
			if(!note[now.x][now.y][(forword+7)%8][length[i+1]][i])
			{
				note[now.x][now.y][(forword+7)%8][length[i+1]][i]=true;
				qq.push({now,(forword+7)%8});
				num++;
			}
		}
		number=num;
	}
	cout<<count<<endl;
	return 0;
}
发布了25 篇原创文章 · 获赞 8 · 访问量 537

추천

출처blog.csdn.net/weixin_44034698/article/details/104873428