1 条题解

  • 0
    @ 2025-8-24 22:37:00

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Dantal10n
    私はもっときれいな 色が好きだな

    搬运于2025-08-24 22:37:00,当前版本为作者最后更新于2023-11-29 18:48:06,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    随便写了一发,交上来看一圈提交记录发现是最短解,看一圈题解区,怎么全是搜相交线段联通块,我不理解。所以来点无脑好写做法。

    读题不需要理解题目给的那一大段条件是什么,先跳过。发现题目要求合并同向有交线段,两种方向可以只写一遍调用两次。为了可读性,分类型写。

    注意到最后必然留下 77 条水平线和 88 条竖直线否则无解。于是考虑计算量为 7!8!O(chk)7!\cdot8!\cdot O(chk) 的枚举全排列做法。发现将两个方向的线段分别重标号会好写很多,把题目的判断条件拉下来手改。最后还有个非同一字母不能有线段交的限制,直接统计总交点数与字母内交点数的差是否为零。

    写完发现样例跑了 5s,于是将竖直线段之间单独的条件判断放在外面,用时直降到 100ms-。直接过了。

    思考+编码时间:1.25h(花了 0.5h 考虑类型转化怎么写的简单点/qd )
    代码长度:1.81K 主播码风本来就这样没有刻意压行。
    看不惯可以左转:LOJ 格式化 ver.

    #include<bits/stdc++.h>
    #define N 100005
    #define F for(int i=1;i<=ns;i++)
    using namespace std;
    int n,nh,nv,ns,ih[N],iv[N];
    struct hr{int l,r,y;}a[N];
    struct vt{int d,u,x;}b[N];
    struct sg{int s,t,p;}c[N];
    bool operator<(const sg &a,const sg &b){if(a.p^b.p)return a.p<b.p;
    	if(a.s^b.s)return a.s<b.s;return a.t>b.t;}
    int s(){stable_sort(c+1,c+1+ns);int t=1;
    	F if(c[i].p^c[t].p||c[i].s>c[t].t)c[++t]=c[i];
    	else c[t].t=max(c[t].t,c[i].t);return t;}
    int l[9],r[9],d[9],u[9],x[9],y[9];
    int crs(int i,int j){return d[j]<=y[i]&&y[i]<=u[j]
    &&l[i]<=x[j]&&x[j]<=r[i];}
    int C(int lh,int rh,int lv,int rv){int c=0;for(int i=lh;i<=rh;i++)
    	for(int j=lv;j<=rv;j++)c+=crs(i,j);return c;}
    signed main(){ios::sync_with_stdio(0),cin.tie(0),cin>>n;
    	for(int i=1,s;i<=n;i++){cin>>s;
    		if(!s)++nh,cin>>a[nh].l>>a[nh].r>>a[nh].y;
    		else ++nv,cin>>b[nv].d>>b[nv].u>>b[nv].x;}
    	ns=nh;F c[i]=(sg){a[i].l,a[i].r,a[i].y};nh=s();F a[i]=(hr){c[i].s,c[i].t,c[i].p};
    	ns=nv;F c[i]=(sg){b[i].d,b[i].u,b[i].x};nv=s();F b[i]=(vt){c[i].s,c[i].t,c[i].p};
    	if(nh^7||nv^8)cout<<"No\n",exit(0);
    	for(int i=1;i<=8;i++)ih[i]=iv[i]=i;
    	do{
    		for(int i=1;i<9;i++)
    			d[i]=b[iv[i]].d,u[i]=b[iv[i]].u,x[i]=b[iv[i]].x;
    		if(d[2]^d[3]||u[2]^u[3]||d[4]^d[5]||u[4]^u[5])continue;
    		do{
    		for(int i=1;i<8;i++)
    		l[i]=a[ih[i]].l,r[i]=a[ih[i]].r,y[i]=a[ih[i]].y;
    		if(y[1]==u[1]&&l[1]<x[1]&&x[1]<r[1]
    		&&d[3]<y[2]&&y[2]<u[2]&&x[2]==l[2]&&r[2]==x[3]
    		&&d[5]==y[3]&&x[4]==l[3]&&r[3]==x[5]&&d[6]<y[5]
    		&&y[5]==d[7]&&u[6]==y[4]&&y[4]==u[7]&&x[6]==l[4]
    		&&l[4]==l[5]&&r[4]==r[5]&&r[5]==x[7]&&d[8]==y[7]
    		&&u[8]==y[6]&&x[8]==l[6]&&l[6]==l[7]&&r[6]==r[7]
    		&&!(C(1,7,1,8)-C(1,1,1,1)-C(2,2,2,3)-C(3,3,4,5)
    		-C(4,5,6,7)-C(6,7,8,8)))cout<<"Yes\n",exit(0);
    		}while(next_permutation(ih+1,ih+8));}
    	while(next_permutation(iv+1,iv+9));
    	cout<<"No\n",exit(0);
    	return 0;
    }
    
    • 1

    信息

    ID
    7570
    时间
    1000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者