首页 > 搜索 > DFS搜索 > hdu 1925 A Foldy but a Goody-计算几何-[解题报告]C++
2013
12-26

hdu 1925 A Foldy but a Goody-计算几何-[解题报告]C++

A Foldy but a Goody

问题描述 :

Suppose you have a strip of paper and are given instructions to fold the paper in one of two ways: an upper fold, where the right end of the paper is brought over to the top of the left end; and a lower fold, where the right end of the paper is brought below the left end. The diagram below illustrates both types of folds.

Now, after meticulously folding the strip several times, you are asked to unfold it by making a 90 degree angle at each crease. The example below shows the result of an upper fold, followed by a lower fold and then an unfolding.

If the left end of the folded strip is placed at the origin (0,0) and the first right angle is at (1,0), it is natural to ask the questions: Where will the second right angle be located? The third right angle? Where will the other end of the strip be located? Well, that’s for us to know and you to figure out.

输入:

The input file will contain multiple test cases. The first line of the file will contain a single integer indicating the number of test cases. Each case will consist of a string of letters U and L indicating a series of upper and lower folds followed by an integer m. The length of the string will be between 1 and 30, inclusive. The value of m identifies a position on the paper. A value of m = 0 indicates the left end (at location (0, 0)). If there are n folds, then a value of m = 2n indicates the right end of the strip. Any value for m between these two extremes represents one of the right angles; m = 1 indicates the first right angle, and so on.

输出:

The input file will contain multiple test cases. The first line of the file will contain a single integer indicating the number of test cases. Each case will consist of a string of letters U and L indicating a series of upper and lower folds followed by an integer m. The length of the string will be between 1 and 30, inclusive. The value of m identifies a position on the paper. A value of m = 0 indicates the left end (at location (0, 0)). If there are n folds, then a value of m = 2n indicates the right end of the strip. Any value for m between these two extremes represents one of the right angles; m = 1 indicates the first right angle, and so on.

样例输入:

3
UL 4
UL 3
LLUL 13

样例输出:

(2,0)
(2,-1)
(1,-2)

每次折叠都是坐标的90度旋转。。。

从后往前处理。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<vector>

using namespace std;

#define nMax  40

char s[nMax];
int m;
class P {
public:
	int x,y;
	P() {};
	P(int x,int y):x(x),y(y) {};
	void out() { printf("(%d,%d)\n",x,y); }
};
P rotate(P p,int k) {
	if(k==1) return P(p.y,-p.x);  // turn right
	else     return P(-p.y,p.x);  // turn left
}
P rotate(P T,P p,int k) {
	P tmp(p.x-T.x,p.y-T.y);
	P ret = rotate(tmp,k);
	return P(ret.x+T.x,ret.y+T.y);
}

P p[40];
int r[40];
P dfs(int m) {
	if(m==0) return p[0];
	long long  i=1LL;
	int j=1;
	while(m>=i) {
		i <<= 1;
		j += 1;
	}
	i >>= 1;j--;
	if(m==i) return p[j];
	m -= i;
	return rotate(p[j],dfs(i-m),r[j]);
}



int main() {
	int t;
	scanf("%d",&t);
	while(t--) {
		scanf("%s%d",s,&m);
		int l = strlen(s);
		p[0]=P(0,0);
		p[1]=P(1,0);
		for(int j=1,i=l-1;i>=0;i--,j++) r[j] = (s[i]=='U'?1:0);
		for(int i=2;i<=l+1;i++)  p[i] = rotate(p[i-1],p[0],r[i-1]);
		P ret = dfs(m);
		ret.out();
	}
	return 0;
}


解题转自:http://blog.csdn.net/utoppia/article/details/10223215