首页 > ACM题库 > HDU-杭电 > HDU 4231-Folding Game [解题报告]HOJ
2015
05-23

HDU 4231-Folding Game [解题报告]HOJ

Folding Game

问题描述 :

Alice and Bob are playing a game. Alice places a rectangular piece of paper in front of Bob with width W and height H. Then she proceeds to fold the paper N times. Each fold is either horizontal or vertical. Folding the paper horizontally leaves another rectangle of the same width W and smaller height h. Similarly, a vertical fold leaves a rectangle with same height H and smaller width w.
In the end, Alice puts her finger on some point on the resulting rectangle and asks ‘Bob, how many layers of paper are directly beneath my finger?’.

输入:

There will be several test cases in the input. Each test case will begin with a line with three integers:
W H N
Where W and H (0 < W,H ≤ 1,000,000) are the width and height of the paper, and N (0 ≤ N ≤ 20) is the number of folds. W and H are guaranteed to be even. On each of the subsequent N lines there will be a letter and a number, separated by a single space:
D K
The letter D is one of { ‘T’, ‘B’, ‘L’, ‘R’ } indicating whether the fold is from the Top, Bottom, Left or Right. It will always be capital. The number K indicates where Alice makes the fold, measured from the given edge. For example, if D is ‘T’, then Alice starts with the paper lying flat, lifts the TOP edge and folds it downward. K is guaranteed to be on the paper, and it is guaranteed to be even.
On the final line of each case there will be two integers:
X Y
Which indicate the point where Alice puts her finger. This is measured from the bottom left corner, with X being the distance towards the right, and Y being the distance towards the top. The point (X,Y) is guaranteed to be on the fully folded paper. Both X and Y are also guaranteed to be odd. Since W, H and K are all even, this assures that the point (X,Y) will not be over any edge or fold.
The input ends with a line with three 0s.

输出:

There will be several test cases in the input. Each test case will begin with a line with three integers:
W H N
Where W and H (0 < W,H ≤ 1,000,000) are the width and height of the paper, and N (0 ≤ N ≤ 20) is the number of folds. W and H are guaranteed to be even. On each of the subsequent N lines there will be a letter and a number, separated by a single space:
D K
The letter D is one of { ‘T’, ‘B’, ‘L’, ‘R’ } indicating whether the fold is from the Top, Bottom, Left or Right. It will always be capital. The number K indicates where Alice makes the fold, measured from the given edge. For example, if D is ‘T’, then Alice starts with the paper lying flat, lifts the TOP edge and folds it downward. K is guaranteed to be on the paper, and it is guaranteed to be even.
On the final line of each case there will be two integers:
X Y
Which indicate the point where Alice puts her finger. This is measured from the bottom left corner, with X being the distance towards the right, and Y being the distance towards the top. The point (X,Y) is guaranteed to be on the fully folded paper. Both X and Y are also guaranteed to be odd. Since W, H and K are all even, this assures that the point (X,Y) will not be over any edge or fold.
The input ends with a line with three 0s.

样例输入:

10 10 1
B 4
5 1
10 10 1
B 4
7 5
10 10 1
T 6
3 1
10 10 1
T 6
9 3
14 10 2
L 4
R 4
3 3
0 0 0

样例输出:

2
1
1
2
3

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
#define M 105

struct info
{
	char side;
	int sou;
	int v;
};

info fold[30];
int w,h,n;
int we,he;
int x,y;

void getdata(void);
int cal(int ws,int hs,int px,int py,int step);

int main()
{
	while (scanf("%d%d%d",&w,&h,&n),w+h+n)
	{
		getdata();
		printf("%d\n",cal(we,he,x,y,n));
	}
	return 0;
}

void getdata(void)
{
	int i;
	we=w;
	he=h;
	for (i=1;i<=n;i++)
	{
		scanf(" %c%d",&fold[i].side,&fold[i].v);
		switch(fold[i].side)
		{
		case 'T':
		case 'B':
			fold[i].sou=he;
			if (he-fold[i].v>=fold[i].v)
				he-=fold[i].v;
			else
			{
				he=fold[i].v;
				/*fold[i].v=he-fold[i].v;
				fold[i].side=fold[i].side=='B'?'T':'B';
				he-=fold[i].v;*/
			}
			break;
		case 'L':
		case 'R':
			fold[i].sou=we;
			if (we-fold[i].v>=fold[i].v)
				we-=fold[i].v;
			else
			{
				we=fold[i].v;
				/*fold[i].v=we-fold[i].v;
				fold[i].side=fold[i].side=='R'?'L':'R';
				we-=fold[i].v;*/
			}
			break;
		}
	}
	scanf("%d%d",&x,&y);
}

int cal(int ws,int hs,int px,int py,int step)
{
	int ans=0;
	int line;
	if (step<1)
		return 1;
	else
	{
		switch (fold[step].side)
		{
		case 'T':
			if (hs>fold[step].v)
			{
				if (py<hs-fold[step].v)
				{
					ans+=cal(ws,hs+fold[step].v,px,py,step-1);
				}
				else
				{
					ans+=cal(ws,hs+fold[step].v,px,py,step-1);
					ans+=cal(ws,hs+fold[step].v,px,hs+(hs-py),step-1);
				}
			}
			else
			{
				line=2*fold[step].v-fold[step].sou;
				if (py>line)
				{
					ans+=cal(ws,fold[step].sou,px,hs+(hs-py)-line,step-1);
					ans+=cal(ws,fold[step].sou,px,py-line,step-1);
				}
				else
				{
					ans+=cal(ws,fold[step].sou,px,hs+(hs-py)-line,step-1);
				}
			}
			break;
		case 'B':
			if (hs>fold[step].v)
			{
				if (py>fold[step].v)
				{
					ans+=cal(ws,hs+fold[step].v,px,py+fold[step].v,step-1);
				}
				else
				{
					ans+=cal(ws,hs+fold[step].v,px,py+fold[step].v,step-1);
					ans+=cal(ws,hs+fold[step].v,px,fold[step].v-py,step-1);
				}
			}
			else
			{
				line=2*fold[step].v-fold[step].sou;
				if (py<hs-line)
				{
					ans+=cal(ws,fold[step].sou,px,py+fold[step].v,step-1);
					ans+=cal(ws,fold[step].sou,px,fold[step].v-py,step-1);
				}
				else
				{
					ans+=cal(ws,fold[step].sou,px,fold[step].v-py,step-1);
				}
			}
			break;
		case 'L':
			if (ws>fold[step].v)
			{
				if (px>fold[step].v)
				{
					ans+=cal(ws+fold[step].v,hs,px+fold[step].v,py,step-1);
				}
				else
				{
					ans+=cal(ws+fold[step].v,hs,px+fold[step].v,py,step-1);
					ans+=cal(ws+fold[step].v,hs,fold[step].v-px,py,step-1);
				}
			}
			else
			{
				line=2*fold[step].v-fold[step].sou;
				if (px<ws-line)
				{
					ans+=cal(fold[step].sou,hs,px+fold[step].v,py,step-1);
					ans+=cal(fold[step].sou,hs,fold[step].v-px,py,step-1);
				}
				else
				{
					ans+=cal(fold[step].sou,hs,fold[step].v-px,py,step-1);
				}
			}
			break;
		case 'R':
			if (ws>fold[step].v)
			{
				if (px<ws-fold[step].v)
				{
					ans+=cal(fold[step].sou,hs,px,py,step-1);
				}
				else
				{
					ans+=cal(fold[step].sou,hs,px,py,step-1);
					ans+=cal(fold[step].sou,hs,ws+(ws-px),py,step-1);
				}
			}
			else
			{
				line=2*fold[step].v-fold[step].sou;
				if (px>line)
				{
					ans+=cal(fold[step].sou,hs,px-line,py,step-1);
					ans+=cal(fold[step].sou,hs,ws+(ws-px)-line,py,step-1);
				}
				else
				{
					ans+=cal(fold[step].sou,hs,ws+(ws-px)-line,py,step-1);
				}
			}
			break;
		}
	}
	return ans;
}