中石油 8375: Origami

Master Grus是一位着名的折纸(纸张折叠)艺术家,他热衷于探索折纸艺术的可能性。为了将来的创作,他现在正在计划基础实验来建立折纸的一般理论。
在他的每个实验中使用一张矩形纸。他将其水平和/或垂直折叠几次,然后在折叠的纸张上打孔。
下图说明了简单实验的折叠过程,该实验对应于下面的样本输入的第三个数据集。将左上方显示的10×8矩形纸折叠三次导致左下方显示6×6方形。在该图中,虚线表示折叠纸张的位置,圆形箭头表示折叠的方向。网格线显示为实线,用于表示矩形形状的大小和折叠的确切位置。颜色密度表示重叠层的数量。在折叠的纸张中打孔A和B,在纸张上形成九个孔,八个在A处,另一个在B处。

你在这个问题上的任务是写一个计算机程序来计算纸张上的孔数,给出一张矩形纸上的信息以及折叠和打孔说明。

输入

输入包含最多1000个数据集,每个数据集采用以下格式。
nmtp 
d1 c1  
...  
dt ct  
x1 y1  
...  
xp yp  
n和m分别是矩形纸的宽度和高度。它们是正整数,最多为32. t和p分别是折叠和打孔指令的数量。它们是最多20的正整数.di和ci对给出如下的第i个折叠指令:
di是1或
2.ci是正整数。
如果di为1,则垂直折叠线的左侧通过ci右侧到左边界,折叠到右侧。
如果di是2,则在下边界上方的ci处通过的水平折叠线的下侧折叠到上侧。
在执行第一个i-1折叠指令之后,如果di为1,则形状的宽度大于ci。否则高度大于ci。(xi + 1/2,yi + 1/2)给出执行第i个打孔指令的点的坐标。原点(0,0)位于最终获得的形状的左下角。xi和yi都是非负整数,它们分别小于形状的宽度和高度。您可以假设没有两个冲压指令在同一位置打孔。
输入的结尾由包含四个零的行指示。

输出

对于每个数据集,输出p行,其中第i行包含第i个打孔指令在纸张中打孔的数量。

这个题很虐心。多了好久还读错题了。

纯模拟就可以了。注意可能会出现c+xx>n的情况。

// lch
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<set>
#include<stack>
#define inf 0x3f3f3f3f
#define LL long long
#define PI acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
const LL mod=998244353;
LL quick( LL x,LL n){LL temp=x,ans=1;while(n){if(n%2){ ans=ans*temp%mod;}n/=2;temp=temp*temp%mod;} return ans%mod;}
using  namespace std;
 int mp[600][600];

int main()
{
   int n,m,t,p;
   while(~scanf("%d%d%d%d",&n,&m,&t,&p)&&(n+m+t+p))
   {
       int xx=0,yy=0;
       mem(mp,0);
       for(int i=0;i<n;i++)
           for(int j=0;j<m;j++)
                mp[i][j]=1;
       while(t--)
       {
           int d,c;
           scanf("%d%d",&d,&c);
           if(d==1)
           {
                for(int i=xx;i<xx+c;i++)
                    for(int j=yy;j<m;j++)
                      {
                          if(xx==0)
                          {
                               mp[2*xx+2*c-i-1][j]+=mp[i][j];
                          }
                          else
                               mp[2*xx+2*c-i-1][j]+=mp[i][j];
                      }
                xx+=c;
                if(n-xx<c) n=xx+c;
           }
           else {
               for(int i=xx;i<n;i++)
                    for(int j=yy;j<yy+c;j++)
                    {
                        if(yy==0)
                            mp[i][2*yy+2*c-j-1]+=mp[i][j];
                        else
                            mp[i][2*yy+2*c-j-1]+=mp[i][j];
                    }
                yy+=c;
                if(m-yy<c) m=yy+c;
           }
         /*  printf("***********\n");
          for(int i=0;i<4;i++)
          {
               for(int j=0;j<3;j++)
                   printf("%d ",mp[i][j]);
               printf("\n");
          }
          printf("***********\n");
       }
       for(int i=0;i<4;i++)
       {
           for(int j=0;j<3;j++)
               printf("%d ",mp[i][j]);
           printf("\n");
       }*/
       }
       int ans=0;
       while(p--)
       {
           int x,y;
           scanf("%d%d",&x,&y);
          // ans+=mp[x+xx][y+yy];
           printf("%d\n",mp[xx+x][yy+y]);
       }

   }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值