Origami, or the art of folding paper(折叠纸张)

Master Grus is a famous origami (paper folding) artist, who is enthusiastic about exploring the possibility of origami art. For future creation, he is now planning fundamental experiments to establish the general theory of origami.One rectangular piece of paper is used in each of his experiments. He folds it horizontally and/or vertically several times and then punches through holes in the folded paper.The following figure illustrates the folding process of a simple experiment, which corresponds to the third data test of the Sample Input below. Folding the 10 × 8 rectangular piece of paper shown at top left three times results in the 6 × 6 square shape shown at bottom left. In the figure, dashed lines indicate the locations to fold the paper and round arrows indicate the directions of folding. Grid lines are shown as solid lines to tell the sizes of rectangular shapes and the exact locations of folding. Color densities represent the numbers of overlapping layers. Punching through holes at A and B in the folded paper makes nine holes in the paper, eight at A and another at B.

在这里插入图片描述

Your mission in this problem is to write a computer program to count the number of holes in the paper, given the information on a rectangular piece of paper and folding and punching instructions.

Input

The input consists of at most 1000 data tests, each in the following format.

  • nn mm tt pp
  • d_1d1​ c_1c1​
  • ...
  • d_tdt​ c_tct​
  • x_1x1​ y_1y1​
  • ...
  • x_pxp​ y_pyp​

n and m are the width and the height, respectively, of a rectangular piece of paper. They are positive integers at most 32. tt and ppare the numbers of folding and punching instructions, respectively. They are positive integers at most 20. The pair of d_idi​ and c_ici​ gives the i_tit​_hh​ folding instruction as follows:

  • d_idi​ is either 1 or 2.
  • c_ici​ is a positive integer.
  • If d_idi​ is 1, the left-hand side of the vertical folding line that passes at c_ici​ right to the left boundary is folded onto the right-hand side.
  • If d_idi​ is 2, the lower side of the horizontal folding line that passes at c_ici​ above the lower boundary is folded onto the upper side.

After performing the first i−1 folding instructions, if d_idi​ is 1, the width of the shape is greater than c_ici​. Otherwise the height is greater than c_ici​. (x_ixi​ + 1\over{2}21​, y_iyi​ + 1\over{2}21​) gives the coordinates of the point where the i_tit​_hh​ punching instruction is performed. The origin (0, 0) is at the bottom left of the finally obtained shape. x_ixi​ and y_iyi​ are both non-negative integers and they are less than the width and the height, respectively, of the shape. You can assume that no two punching instructions punch holes at the same location.

The end of the input is indicated by a line containing four zeros.

Output

For each data test, output pp lines, the i_tit​_hh​ of which contains the number of holes punched in the paper by the i_tit​_hh​ punching instruction.

样例输入复制

2 1 1 1
1 1
0 0
1 3 2 1
2 1
2 1
0 0
10 8 3 2
2 2
1 3
1 1
0 1
3 4
3 3 3 2
1 2
2 1
1 1
0 1
0 0
0 0 0 0

样例输出复制

2
3
8
1
3
6

 

题目大意 题目给出每次折纸的方法(上下或者左右),折叠后在纸上打孔,求出打孔位置折叠了几层。

解题思路 题意有两种折法,一是从左往右折,二是从下往上折;而打孔的坐标是以左下为原点开始的,行的编号从下往 上增大。 因此为便于处理,将整个过程上下颠倒,左右不变:即第二种折纸方式看作从上往下折,打孔坐标的 行号从上往下增大。 
用两个一维数组分别保存由于上下折、左右折引起的纸的层数变化,每次折纸后对其进行更新,并记录左上 角那个点的坐标,在下次对折时当作新的原点。后的结果为左右折纸和上下折纸所造成层数的乘积

 

# include <iostream>
# include <algorithm>
# include <cstring>
# include <math.h>
# include <stdio.h>
# include <vector>
# include <map>
using namespace std;
# define ll long long
int row[10100];
int col[10100];
int main(){
	
	int n,m,t,p;
	while(cin >> n >> m >> t >> p){
		if(n == 0 && m == 0 && t == 0 && p == 0){
			break;
		}
		int d,c;
		int dx = 0;
		int dy = 0;//记录x和y的变化 
		memset(row,0,sizeof(row));
		memset(col,0,sizeof(col));
		for(int i = 0; i < m; i++){
			row[i] = 1;
		}
		for(int i = 0; i < n; i++){
			col[i] = 1;
		}
		for(int i = 1; i <= t; i++){
			cin >> d >> c;
			if(d == 1){
				for(int j = dx+c; j < dx+c*2; j++){
					col[j] += col[2*dx+2*c-1-j];
				}
				dx += c;
			}
			else{
				for(int j = dy+c; j < dy+c*2; j++){
					row[j] += row[2*dy+2*c-1-j];
				}
				dy += c;
			}
			/*for(int j = 0; j < m; j++){
				cout << col[j] << " ";
			}
			cout << endl;
			for(int j = 0; j < n; j++){
				cout << row[j] << " ";
			}
			cout << endl;*/
		}
		int x,y;
		for(int i = 0; i < p; i++){
			cin >> x >> y;
			cout << col[dx+x]*row[dy+y] << endl;
		}
	}
	
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值