正题
题目大意
每个点往可以往4个方向之一发射光,要求光不可以相交且不可以经过别的点,求方案总数。
解题思路
将点按xxx排序,
设fl,r,u,d,if_{l,r,u,d,i}fl,r,u,d,i表示放到第iii个点,最上面的向下发射的点为lll,最下面的向上发射的点为rrr,最上面的向右发射的点为uuu,最下面的向右发射的点为ddd。
然后每次枚举方向,之后判断一下,且更新新的。最后一维要滚动。
就是细节很恶心
codecodecode
#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include<cstdio>
#include<algorithm>
using namespace std;
const int XJQ=998244353,N=55;
struct node{int x,y;
}a[N];
int n,ans;
int f[N][N][N][N][2];
int Min(int x,int y)
{if(!y) return x;if(!x) return y;if(a[x].y<a[y].y) return x;return y;
}
int Max(int x,int y)
{if(!y) return x;if(!x) return y;if(a[x].y>a[y].y)return x;return y;
}
bool cmp(node x,node y){return x.x<y.x||(x.x==y.x&&x.y<y.y);
}
bool check(int i,int j,int k)
{if(j==0&&a[k].x==a[i+1].x&&a[k].y>a[i+1].y)return false; if(j==1&&a[k].x==a[i+1].x&&a[k].y<a[i+1].y)return false;if(j==2&&a[k].y==a[i+1].y&&a[k].x<a[i+1].x)return false; if(j==3&&a[k].y==a[i+1].y&&a[k].x>a[i+1].x)return false; return true;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);sort(a+1,a+1+n,cmp);int p=0,q=1; f[0][0][0][0][0]=1;for(int i=0;i<n;i++){for(int j=0;j<4;j++){bool flag=false;for(int k=1;k<=n;k++)if(!check(i,j,k)){flag=true;break;}if(flag)continue;for(int l=0;l<=i;l++)for(int r=0;r<=i;r++)for(int u=0;u<=i;u++)for(int d=0;d<=i;d++){if(f[l][r][u][d][p]){if(j==0&&(a[l].y<a[i+1].y||!l))(f[l][r][Min(i+1,u)][d][q]+=f[l][r][u][d][p])%=XJQ;if(j==1&&(a[r].y>a[i+1].y||!r))(f[l][r][u][Max(i+1,d)][q]+=f[l][r][u][d][p])%=XJQ;if(j==2&&((a[u].y>a[i+1].y&&a[d].y<a[i+1].y)||(!u&&!d)||(a[u].y>a[i+1].y&&!d)||(a[d].y<a[i+1].y&&!u)))(f[l][r][u][d][q]+=f[l][r][u][d][p])%=XJQ;if(j==3)(f[Max(i+1,l)][Min(i+1,r)][u][d][q]+=f[l][r][u][d][p])%=XJQ;}}}p=(p+1)&1;q=(q+1)&1;for(int l=0;l<=n;l++)for(int r=0;r<=n;r++)for(int u=0;u<=n;u++)for(int d=0;d<=n;d++)f[l][r][u][d][q]=0;}for(int l=0;l<=n;l++)for(int r=0;r<=n;r++)for(int u=0;u<=n;u++)for(int d=0;d<=n;d++){//if(f[l][r][u][d][p]) printf("%d-%d-%d-%d:%d\n",l,r,u,d,f[l][r][u][d][p]);ans=(ans+f[l][r][u][d][p])%XJQ;}printf("%d",ans);
}