upc 8375: Origami(模拟题)

8375: Origami

题目描述

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 dataset 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.


输入

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

n m t p

d1 c1

...

dt ct

x1 y1

扫描二维码关注公众号,回复: 3286413 查看本文章

...

xp yp

n and m are the width and the height, respectively, of a rectangular piece of paper. They are positive integers at most 32. t and p are the numbers of folding and punching instructions, respectively. They are positive integers at most 20. The pair of di and ci gives the i-th folding instruction as follows:

di is either 1 or 2.

ci is a positive integer.

If di is 1, the left-hand side of the vertical folding line that passes at ci right to the left boundary is folded onto the right-hand side.

If di is 2, the lower side of the horizontal folding line that passes at ci above the lower boundary is folded onto the upper side.

After performing the first i−1 folding instructions, if di is 1, the width of the shape is greater than ci. Otherwise the height is greater than ci. (xi + 1/2, yi + 1/2) gives the coordinates of the point where the i-th punching instruction is performed. The origin (0, 0) is at the bottom left of the finally obtained shape. xi and yi 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.


输出

For each dataset, output p lines, the i-th of which contains the number of holes punched in the paper by the i-th 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


来源/分类

ICPC Japan IISF 2018

[总结]:

很生气,以后都要注意休息才行,对于这种边界问题要想清楚才行.

本来我就不怎么想做了,因为我对于这种二维的,本来都是从右上角延伸的.

现在都变成左下角延伸了,以后就要会输出才行.不然看不出来究竟是哪里出问题.

今天就是长记性了.

[题意]:

这个题就是按照图上面的操作进行即可.

比如说示例3:

d=1时,往右翻即可.

d=2时,往上翻即可.

这里有个小细节要注意,我们的c时边界,但是我们操作时是按照格子的.

 [ 题解 ]:

这个问题关键时处理好边界问题,如果能妥当地处理,必须知道,返折的过程。

如果,左边>右边.R要更新。

同理,下面>上面.U要更新。

对于对折的过程必须 (L / D)+2*C  延伸两倍的区域,然后对进行  (L / D)+2C-K。

注意这个K必须时从1开始,不能用 i 来代替,不然你错哪里都不知道,

我们只要知道,距离边界的距离进行对称处理。

而不是下标,因为我们的下标会随着这个图的返折不断延伸到远处。

要是大家不能理解,就看看代码,把注释去掉,看一看这个表就可以实现了。

#include<bits/stdc++.h>
using namespace std;
const int N=1100;
int a[N][N];
int n,m,t,p,d,c,U,D,L,R;
void init(){
    memset(a,0,sizeof(a));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            a[i][j]=1;
        }
    }
}
void show(){
    for(int j=U-1;j>=D;j--){
        for(int i=L;i<R;i++){
            printf("%d%c",a[i][j],i==R-1?'\n':' ');
        }
    }
}
int main()
{
    while(~scanf("%d%d%d%d",&n,&m,&t,&p),(n||m||t||p)){
        init();
        D=0,L=0,U=m,R=n;
        show();
        while(t--){
            scanf("%d%d",&d,&c);
            if(d==1){
                for(int i=L,k=1;i<L+c;i++,k++){
                    for(int j=D;j<U;j++){
                        a[L+2*c-k][j]+=a[i][j];
                        //a[i][j]=0;
                    }
                }
                c=L+c;
                if(c-L>R-c){
                    R=(c-L)+c;
                }
                L=c;
            }else{
                for(int i=L;i<R;i++){
                    for(int j=D,k=1;j<D+c;j++,k++){
                        a[i][D+2*c-k]+=a[i][j];
                        //a[i][j]=0;
                    }
                }
                c=D+c;
                if(c-D>U-c){
                    U=(c-D)+c;
                }
                D=c;
            }
            //printf("L:%d R:%d D:%d U:%d\n",L,R,D,U);
            //show();
        }
        int x,y;
        for(int i=1;i<=p;i++){
            scanf("%d%d",&x,&y);
            printf("%d\n",a[x+L][y+D]);
        }
    }
    return 0;
}

 这种是:ppr大佬提供想法,具体实现还是孙大佬和ppr合作。

#include<bits/stdc++.h>
using namespace std;
const int N=100;
int a[N][N],b[N][N];
 
int n,m,t,p,d,c;
void init(){
    //memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            a[i][j]=1;
        }
    }
}
int main()
{
    while(~scanf("%d%d%d%d",&n,&m,&t,&p),(n||m||t||p)){
        init();
        while(t--){
            scanf("%d%d",&d,&c);
            if(d==1){
                for(int i=0;i<(2*c<=n?c:n-c);i++){
                    for(int j=0;j<m;j++){
                        b[i][j]=a[c+i][j]+a[c-i-1][j];
                    }
                }
                if(2*c<=n){
                    for(int i=c;i<n-c;i++){
                        for(int j=0;j<m;j++){
                            b[i][j]=a[c+i][j];
                        }
                    }
                    n=n-c;
                    for(int i=0;i<n;i++){
                        for(int j=0;j<m;j++){
                            a[i][j]=b[i][j];
                        }
                    }
                }else{
                    for(int i=n-c,k=1;i<c;i++,k++){
                        for(int j=0;j<m;j++){
                            b[i][j]=a[2*c-n-k][j];
                        }
                    }
                    n=c;
                    for(int i=0;i<n;i++){
                        for(int j=0;j<m;j++){
                            a[i][j]=b[i][j];
                        }
                    }
                }
            }else{
                for(int i=0;i<n;i++){
                    for(int j=0;j<(2*c<=m?c:m-c);j++){
                        b[i][j]=a[i][c+j]+a[i][c-j-1];
                    }
                }
                if(2*c<=m){
                    for(int i=0;i<n;i++){
                        for(int j=c;j<m-c;j++){
                            b[i][j]=a[i][c+j];
                        }
                    }
                    m=m-c;
                    for(int i=0;i<n;i++){
                        for(int j=0;j<m;j++){
                            a[i][j]=b[i][j];
                        }
                    }
                }else{
                    for(int i=0;i<n;i++){
                        for(int j=m-c,k=1;j<c;j++,k++){
                            b[i][j]=a[i][2*c-m-k];
                        }
                    }
                    m=c;
                    for(int i=0;i<n;i++){
                        for(int j=0;j<m;j++){
                            a[i][j]=b[i][j];
                        }
                    }
                }
            }
            //show();
            //printf("####(0,0):%d\n",a[0][0]);
        }
        for(int i=1;i<=p;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            
            printf("%d\n",a[x][y]);
        }
    }return 0;
}

还有一种是链表操作(由孙大佬提供):

#include<bits/stdc++.h>
using namespace std;
int a[33];
int xx[33],yy[33];
int main()
{
    int n,m,t,p;
    while(scanf("%d%d%d%d",&n,&m,&t,&p),(n||m||p||t))
    {
        list<int>l1,l2;
        int c,d,x,y;
        for(int i=0;i<n;i++)
        l1.push_back(1);
        for(int i=0;i<m;i++)
        l2.push_back(1);
        while(t--)
        {
            scanf("%d%d",&d,&c);
            if(d==1)
            {
                for(int i=0;i<c;i++)
                    a[i]=l1.front(),l1.pop_front();
                if(2*c<=n)
                {
                    for(int i=c-1;i>=0;i--)
                    a[i]+=l1.front(),l1.pop_front();
                    for(int i=0;i<c;i++)
                    l1.push_front(a[i]);
                    n-=c;
                }
                else
                {
                    for(int i=c-1;!l1.empty();i--)
                    a[i]+=l1.front(),l1.pop_front();
                    for(int i=0;i<c;i++)
                    l1.push_front(a[i]);
                    n=c;
                }
            }
            else
            {
                for(int i=0;i<c;i++)
                    a[i]=l2.front(),l2.pop_front();
                if(2*c<=m)
                {
                    for(int i=c-1;i>=0;i--)
                    a[i]+=l2.front(),l2.pop_front();
                    for(int i=0;i<c;i++)
                    l2.push_front(a[i]);
                    m-=c;
                }
                else
                {
                    for(int i=c-1;!l2.empty();i--)
                    a[i]+=l2.front(),l2.pop_front();
                    for(int i=0;i<c;i++)
                    l2.push_front(a[i]);
                    m=c;
                }
            }
        }
        for(int i=0;i<n;i++)
        xx[i]=l1.front(),l1.pop_front();
        for(int i=0;i<m;i++)
        yy[i]=l2.front(),l2.pop_front();
        while(p--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d\n",xx[x]*yy[y]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/81986293
UPC