题目描述:
有一个蛋糕,从上方看是一个正方形,中心有一个正方形区域为空。
两个正方形的中心都在(0,0)位置,并且它们的边都与某条坐标轴平行。
P将竖直或水平地切蛋糕,每一刀都将经过整个蛋糕(即不会因为中心的洞而中断)。
给定他切蛋糕的位置,请求出蛋糕总共被切成了多少份。
输入:
输出:
对于每组数据,依次输出一行答案,表示蛋糕最终切成的块数。
算法标签:思维模拟
思路:
一眼看觉得蛮简单的,但是写了好久还是不对...气..最终解是n*m枚举每一个方块,倘若你两个维度都切在分割处贡献为0,倘若一维在分割处,另一维两条线位于中间小块两侧,此时贡献为2,其他时候贡献都为1,可以手动模拟一下。
以下代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define il inline #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int N=5003;int n,m,a[N],b[N],ans;bool pd; il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;} il bool pd1(int x){if(a[x]<=m&&a[x]>=-m)return 1;return 0;} il bool pd2(int x){if(b[x]<=m&&b[x]>=-m)return 1;return 0;} int main() { int T=read();while(T--){ n=read();m=read();a[0]=read();b[0]=read();ans=0; for(int i=1;i<=a[0];i++)a[i]=read();a[++a[0]]=-n;a[++a[0]]=n; for(int i=1;i<=b[0];i++)b[i]=read();b[++b[0]]=-n;b[++b[0]]=n; sort(a+1,a+1+a[0]);sort(b+1,b+1+b[0]); for(int i=1;i<a[0];i++){ if(a[i]<-n||a[i+1]>n)continue;if(pd1(i)&&pd1(i+1))pd=1;else pd=0; for(int j=1;j<b[0];j++){ if(b[j]<-n||b[j+1]>n)continue; if(pd2(j)&&pd2(j+1)&&pd)continue; if(pd&&b[j]<-m&&b[j+1]>m)ans+=2; else if(pd2(j)&&pd2(j+1)&&a[i]<-m&&a[i+1]>m)ans+=2; else ans++; } } printf("%d ",ans); } return 0; }