[Programming thinking and practice of CSP-M1 C] terrible cosmic rays

Subject description:

Cosmic rays propagate (can be regarded as a two-dimensional grid map) in an infinite two-dimensional plane, the default initial upward direction. Cosmic rays are emitted after a distance split in this direction of about 45 . Split the two cosmic rays, while the power of the same! Cosmic rays will split n times, each time after a forward split i units of length.

Enter a description:

Input of the first line contains a positive integer n (n <= 30) represented by cosmic rays split n times
the second line contains n integers, A . 1 , `A 2 , ..., A n , A number of I I (A i <= 5) indicates how many units of length i-th division of cosmic rays would go in the original direction.

Sample input:

4
4 2 2 3

Output Description:

The output of a number ans, represents the number of units of cosmic rays traveled.

Sample output:

39

Data Point Description:

data point n
10% <=10
40% <=20
100% <=30

Ideas:

The difficulty is to point while repeating the determination can not have a large time complexity. Bool can create a larger array, showing two flat, bool value is represented by whether the point has been passed. Because A I <=. 5, n-<= 30, so that the array has the size of 300 * 300 enough, this may take a little larger, using thought bfs will each emit cosmic rays, each layer considered bfs extension, i.e., using a node after each queue holds the extension direction of the next emission. But this approach obviously violent bfs time out, therefore, we have established a five-dimensional array, each dimension of meaning are x-coordinate, y coordinates, direction, length, extended many times. Thus, the marker may be used to spread one point, this point has no record to be pressed into the queue, if the queue has entered again pressed will go again to the same path, so the extensions can be discarded once repeated point, so that we can greatly reduce the time complexity of the program.

Reflection:

1, not previously thought of using an array of five, but the use of four-dimensional array, how many times did not extend this dimension, but when the test test7 appeared WA, realized that, if there is no fifth dimension, previous extension the recording will be repeated later in the removal of point of impact, that is, after a few might want to extend the point and has been extended several times before repeating the point, but they are just the same this step, and the next expansion may be different, and therefore if these as a point of removing duplicate points will undoubtedly part of the case is lost, hence the use of a five-dimensional arrays, or four-dimensional arrays can also be written to zero before the next layer of expanded every mark.
2, since each layer extension needs to re-tag, and each layer is the same extension point in its transmission length, so that in the five-dimensional array length dimension somewhat redundant, can be removed.
3, to determine the direction of the division, wrote a lengthy switch statement to judge, but later found to change direction after each division there is a pattern, that is, after each split into a left and right direction, the direction of the original 45 . Original direction if reverse direction of the clockwise after recording in an array, the split direction of the original direction and + 1mod8 + 7mod8. This simplifies the determination of the direction.

Code:

#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

Guess you like

Origin blog.csdn.net/weixin_44034698/article/details/104873428