2018.10.25-dtoj-2903-蛋糕(cake)

题目描述:

有一个蛋糕,从上方看是一个正方形,中心有一个正方形区域为空。

两个正方形的中心都在(0,0)位置,并且它们的边都与某条坐标轴平行。

P将竖直或水平地切蛋糕,每一刀都将经过整个蛋糕(即不会因为中心的洞而中断)。

给定他切蛋糕的位置,请求出蛋糕总共被切成了多少份。

输入:

 输出:

对于每组数据,依次输出一行答案,表示蛋糕最终切成的块数。

算法标签:思维模拟

思路:

一眼看觉得蛮简单的,但是写了好久还是不对...气..最终解是n*m枚举每一个方块,倘若你两个维度都切在分割处贡献为0,倘若一维在分割处,另一维两条线位于中间小块两侧,此时贡献为2,其他时候贡献都为1,可以手动模拟一下。

以下代码:

#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;
}
View Code
原文地址:https://www.cnblogs.com/Jessie-/p/9853001.html