☰
UVa 999 Book Signatures
2026/10/14 6:57:20 网站建设 项目流程

题目描述

手工制作一本书时,需要将内容打印到纸上(每张纸444页,每面222页),然后将纸对折,再沿折痕装订到封面。由于一次装订的纸张数量有限(最多323232张),当书页较多时,需要分成多个“书帖”(signature\texttt{signature}signature)来装订。一个书帖是一叠打印好并折叠好的纸张。给定书的总页数nnn和每个书帖包含的纸张数mmm,要求输出每个书帖中每张纸每面应打印的页码。若总页数不是每个书帖页数(4×m4 \times m4×m)的整数倍,则在书末添加空白页补足。

输入格式

输入包含多组测试数据。每组数据占一行,包含两个整数nnn和mmm,中间用一个分号分隔。nnn表示书的总页数,mmm表示每个书帖包含的纸张数。满足0<n≤100000 < n \le 100000<n≤10000,0<m≤320 < m \le 320<m≤32。

输出格式

对于每组测试数据,输出每个书帖的打印说明。每个书帖首先输出一行signature i,其中iii为书帖编号(从111开始)。接着对每张纸输出一行,格式为sheet j: pages p2 and p4 (front); pages p3 and p1 (back),其中jjj为纸张编号(从111开始),p1p1p1、p2p2p2、p3p3p3、p4p4p4为该纸张对应的页码。相邻两组测试数据的输出之间用一个空行分隔。所有输出均使用小写字母,并严格按照样例中的空格、冒号和分号格式。

样例输入

9;2

样例输出

signature 1 sheet 1: pages 2 and 7 (front); pages 8 and 1 (back) sheet 2: pages 4 and 5 (front); pages 6 and 3 (back) signature 2 sheet 1: pages 10 and 15 (front); pages 16 and 9 (back) sheet 2: pages 12 and 13 (front); pages 14 and 11 (back)

题目分析

该问题要求根据书的总页数和每个书帖的纸张数,计算并输出每个书帖中每张纸每面应打印的页码。一个书帖包含mmm张纸,每张纸有444页(正面222页,背面222页),因此一个书帖共4m4m4m页。若总页数nnn不是4m4m4m的整数倍,则需要补充空白页使总页数变为4m4m4m的整数倍。设补充后的总页数为NNN,则书帖数量为N/(4m)N / (4m)N/(4m)。对于每个书帖,其页码范围从startPage\textit{startPage}startPage到endPage\textit{endPage}endPage,其中endPage=startPage+4m−1\textit{endPage} = \textit{startPage} + 4m - 1endPage=startPage+4m−1。在书帖内部,纸张的折叠方式决定了页码的对应关系。对于第jjj张纸,其正面左侧页码为leftPage\textit{leftPage}leftPage,右侧页码为rightPage−1\textit{rightPage} - 1rightPage−1;背面左侧页码为rightPage\textit{rightPage}rightPage,右侧页码为leftPage+1\textit{leftPage} + 1leftPage+1。每处理一张纸后,leftPage\textit{leftPage}leftPage增加222,rightPage\textit{rightPage}rightPage减少222。按照此规律逐张输出即可。

解题思路

对于每组数据,首先读取nnn和mmm。若nnn不能被4m4m4m整除,则将nnn增加到4m4m4m的倍数。计算书帖数量signature=n/(4m)\textit{signature} = n / (4m)signature=n/(4m)。初始化startPage=1\textit{startPage} = 1startPage=1,endPage=startPage+4m−1\textit{endPage} = \textit{startPage} + 4m - 1endPage=startPage+4m−1。对于每个书帖iii(从111到signature\textit{signature}signature),输出signature i。然后初始化leftPage=startPage\textit{leftPage} = \textit{startPage}leftPage=startPage,rightPage=endPage\textit{rightPage} = \textit{endPage}rightPage=endPage。对于每张纸jjj(从111到mmm),计算四个页码:page1=leftPage\textit{page1} = \textit{leftPage}page1=leftPage,page2=leftPage+1\textit{page2} = \textit{leftPage} + 1page2=leftPage+1,page3=rightPage\textit{page3} = \textit{rightPage}page3=rightPage,page4=rightPage−1\textit{page4} = \textit{rightPage} - 1page4=rightPage−1。按照格式输出正面和背面的页码。然后更新leftPage+=2\textit{leftPage} += 2leftPage+=2,rightPage−=2\textit{rightPage} -= 2rightPage−=2。处理完一个书帖后,更新startPage=endPage+1\textit{startPage} = \textit{endPage} + 1startPage=endPage+1,endPage=startPage+4m−1\textit{endPage} = \textit{startPage} + 4m - 1endPage=startPage+4m−1。注意相邻测试数据之间输出空行。

代码实现

// Book Signatures// UVa ID: 999// Verdict: Accepted// Submission Date: 2017-03-14// UVa Run Time: 0.040s//// 版权所有(C)2017,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;intmain(intargc,char*argv[]){cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);intn,m,signature,cases=0;charsemiColon;while(cin>>n>>semiColon>>m){if(cases++>0)cout<<'\n';if((n%(4*m))!=0)n+=(4*m-(n%(4*m)));signature=n/(4*m);intstartPage=1,endPage=startPage+4*m-1;for(inti=1;i<=signature;i++){cout<<"signature "<<i<<'\n';intleftPage=startPage,rightPage=endPage;for(intj=1;j<=m;j++){cout<<" sheet "<<j<<":";intpage1=leftPage,page2=leftPage+1,page3=rightPage,page4=rightPage-1;cout<<" pages "<<page2<<" and "<<page4<<" (front);";cout<<" pages "<<page3<<" and "<<page1<<" (back)\n";leftPage+=2,rightPage-=2;}startPage=endPage+1;endPage=startPage+4*m-1;}}return0;}

总结

本题的关键在于理解书籍装订时页码的排列规律。一个书帖内的纸张折叠后,页码的对应关系是固定的:最外层纸张的正面左侧是最小页码,右侧是最大页码减一;背面左侧是最大页码,右侧是最小页码加一。随着纸张层数向内,页码逐渐向中间靠拢。通过维护leftPage\textit{leftPage}leftPage和rightPage\textit{rightPage}rightPage两个指针,可以方便地计算出每张纸的四个页码。注意处理总页数不是4m4m4m整数倍时补空白页的情况,以及相邻测试数据之间的空行分隔。掌握这种页码排列的规律,对于解决书籍装订、打印排版类问题具有重要的参考价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询