提出 #41341685


ソースコード 拡げる

#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r)for(ll i=(l);i<(r);i++)

using ll=long long;
using point=array<ll,3>;
using line=array<point,2>;

ll gcd(ll p,ll q){while(q){p%=q;swap(p,q);}return abs(p);}

class frac{
public:
	ll nume,deno;

	frac() : nume(0), deno(1) {}
	frac(ll n): nume(n), deno(1) {}
	frac(ll n,ll d){
		assert(d);
		if(d<0){
			nume=-n;
			deno=-d;
		}else{
			nume=n;
			deno=d;
		}
		reduce();
	}
	void reduce(){
		ll d=gcd(nume,deno);
		nume/=d;
		deno/=d;
    }
	frac operator-(ll n){return frac(nume-n*deno,deno);}
	frac operator+(ll n){return frac(nume+n*deno,deno);}
	frac operator*(frac&x){return frac(nume*x.nume,deno*x.deno);}
	bool operator<(ll x){return nume<x*deno;}
	
	friend bool operator==(const frac&x,const frac&y){return x.nume==y.nume&&x.deno==y.deno;}
	friend bool operator<(const frac&x,const frac&y){return x.nume*y.deno<y.nume*x.deno;}
};

array<frac,2> get_vec(point&p,point&q){
	frac dy=frac(p[1]-q[1],p[0]-q[0]);
	frac dz=frac(p[2]-q[2],p[0]-q[0]);
	return {dy,dz};
}

using point_frac=array<frac,3>;
pair<point_frac,bool> get_intersect(line l1,line l2){
	//z=0に射影して交点(x,y)を求める。平行でない、x=aの平面上にない
	ll deno=(l1[0][0]-l1[1][0])*(l2[0][1]-l2[1][1])-(l2[0][0]-l2[1][0])*(l1[0][1]-l1[1][1]);
	if(!deno){
		//平行でない2直線がz=0に射影して平行⇒射影した結果同一直線上にある、すなわち平面px+qy=0上にある
		//平面x=aの上にないので、y=0に射影すれば平行でない。y,zをswapしてやりなおし
		swap(l1[0][1],l1[0][2]);
		swap(l1[1][1],l1[1][2]);
		swap(l2[0][1],l2[0][2]);
		swap(l2[1][1],l2[1][2]);
		auto[p,f]=get_intersect(l1,l2);
		swap(p[1],p[2]);
		return{p,f};
	}
	ll xnume=  l1[0][0]*l2[0][0]*(l1[1][1]-l2[1][1])-l1[0][0]*l2[1][0]*(l1[1][1]-l2[0][1])-l1[1][0]*l2[0][0]*(l1[0][1]-l2[1][1])+l1[1][0]*l2[1][0]*(l1[0][1]-l2[0][1]);
	ll ynume=-(l1[0][1]*l2[0][1]*(l1[1][0]-l2[1][0])-l1[0][1]*l2[1][1]*(l1[1][0]-l2[0][0])-l1[1][1]*l2[0][1]*(l1[0][0]-l2[1][0])+l1[1][1]*l2[1][1]*(l1[0][0]-l2[0][0]));
	frac x=frac(xnume,deno),y=frac(ynume,deno);
	//z座標が等しいか確認
	frac dz1=frac(l1[0][2]-l1[1][2],l1[0][0]-l1[1][0]);
	frac dz2=frac(l2[0][2]-l2[1][2],l2[0][0]-l2[1][0]);
	frac z1=(x-l1[0][0])*dz1+l1[0][2];
	frac z2=(x-l2[0][0])*dz2+l2[0][2];
	if(z1==z2)return {{x,y,z1},true};
	return {{},false};
}

int main(){
	int n;
	cin >> n;
	vector<point>p(n);
	rep(i,0,n)cin >> p[i][0] >> p[i][1] >> p[i][2];
	
	//極大な線分を列挙する
	//その直線の端から見たとき何個の点が隠れるか数えておく
	vector<line>L;
	vector<int>count;
	rep(i,0,n)rep(j,0,n){
		if(p[i][0]>=p[j][0])continue;
		//pix<pjx
		auto dxdy=get_vec(p[i],p[j]);
		int cnt=0;
		bool ok=true;
		rep(k,0,n){
			if(p[i][0]==p[k][0]||p[k][0]==p[j][0])continue;
			if(dxdy==get_vec(p[i],p[k])){
				if(p[i][0]<=p[k][0]&&p[k][0]<=p[j][0]){
					cnt++;
				}else{
					ok=false;
					break;
				}
			}
		}
		if(ok){
			L.push_back({p[i],p[j]});
			count.push_back(cnt+1);
		}
	}
	
	int nn=L.size();
	if(nn==0){
		cout << n << endl;
		return 0;
	}

	//直線の交点をkeyに、その交点を通る直線のsetを持つ
	map<point_frac,set<int>>temp;
	rep(i,0,nn)rep(j,i+1,nn){
		if(get_vec(L[i][0],L[i][1])==get_vec(L[j][0],L[j][1]))continue;
		auto[p,f]=get_intersect(L[i],L[j]);
		if(!f)continue;
		if(p[0]<0){
			temp[p].insert(i);
			temp[p].insert(j);
		}
	}
	
	int ans=*max_element(count.begin(),count.end());
	for(auto[_,s]:temp){
		int tans=0;
		for(auto i:s)tans+=count[i];
		ans=max(ans,tans);
	}
	cout << n-ans << endl;
}

提出情報

提出日時
問題 G - Worst Picture
ユーザ kyopro_friends
言語 C++ (GCC 9.2.1)
得点 600
コード長 3729 Byte
結果 AC
実行時間 1184 ms
メモリ 16036 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 600 / 600
結果
AC × 2
AC × 62
セット名 テストケース
Sample sample_01.txt, sample_02.txt
All hand.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, random_21.txt, random_22.txt, random_23.txt, random_24.txt, random_25.txt, random_26.txt, random_27.txt, random_28.txt, random_29.txt, random_30.txt, random_31.txt, random_32.txt, random_33.txt, random_34.txt, random_35.txt, random_36.txt, random_37.txt, random_38.txt, random_39.txt, random_40.txt, random_41.txt, random_42.txt, random_43.txt, random_44.txt, random_45.txt, random_46.txt, random_47.txt, random_48.txt, random_49.txt, random_50.txt, random_51.txt, random_52.txt, random_53.txt, random_54.txt, random_55.txt, random_56.txt, random_57.txt, random_58.txt, random_59.txt, sample_01.txt, sample_02.txt
ケース名 結果 実行時間 メモリ
hand.txt AC 182 ms 16036 KiB
random_01.txt AC 2 ms 3508 KiB
random_02.txt AC 3 ms 3292 KiB
random_03.txt AC 2 ms 3508 KiB
random_04.txt AC 2 ms 3300 KiB
random_05.txt AC 2 ms 3508 KiB
random_06.txt AC 3 ms 3472 KiB
random_07.txt AC 2 ms 3360 KiB
random_08.txt AC 2 ms 3308 KiB
random_09.txt AC 2 ms 3512 KiB
random_10.txt AC 3 ms 3352 KiB
random_11.txt AC 2 ms 3400 KiB
random_12.txt AC 2 ms 3404 KiB
random_13.txt AC 2 ms 3364 KiB
random_14.txt AC 2 ms 3348 KiB
random_15.txt AC 2 ms 3508 KiB
random_16.txt AC 1163 ms 3584 KiB
random_17.txt AC 3 ms 3480 KiB
random_18.txt AC 1178 ms 3676 KiB
random_19.txt AC 3 ms 3344 KiB
random_20.txt AC 1184 ms 3656 KiB
random_21.txt AC 2 ms 3508 KiB
random_22.txt AC 1161 ms 3584 KiB
random_23.txt AC 198 ms 3388 KiB
random_24.txt AC 336 ms 3460 KiB
random_25.txt AC 93 ms 3372 KiB
random_26.txt AC 347 ms 3476 KiB
random_27.txt AC 7 ms 3472 KiB
random_28.txt AC 353 ms 3448 KiB
random_29.txt AC 55 ms 3516 KiB
random_30.txt AC 346 ms 3700 KiB
random_31.txt AC 56 ms 3564 KiB
random_32.txt AC 2 ms 3296 KiB
random_33.txt AC 2 ms 3476 KiB
random_34.txt AC 297 ms 3532 KiB
random_35.txt AC 206 ms 3480 KiB
random_36.txt AC 391 ms 3484 KiB
random_37.txt AC 204 ms 3564 KiB
random_38.txt AC 566 ms 3592 KiB
random_39.txt AC 477 ms 3380 KiB
random_40.txt AC 2 ms 3508 KiB
random_41.txt AC 2 ms 3536 KiB
random_42.txt AC 234 ms 6316 KiB
random_43.txt AC 249 ms 5412 KiB
random_44.txt AC 142 ms 5608 KiB
random_45.txt AC 326 ms 5324 KiB
random_46.txt AC 564 ms 4764 KiB
random_47.txt AC 561 ms 4072 KiB
random_48.txt AC 3 ms 3512 KiB
random_49.txt AC 2 ms 3508 KiB
random_50.txt AC 2 ms 3456 KiB
random_51.txt AC 2 ms 3300 KiB
random_52.txt AC 2 ms 3360 KiB
random_53.txt AC 2 ms 3292 KiB
random_54.txt AC 2 ms 3400 KiB
random_55.txt AC 2 ms 3364 KiB
random_56.txt AC 2 ms 3472 KiB
random_57.txt AC 2 ms 3300 KiB
random_58.txt AC 2 ms 3508 KiB
random_59.txt AC 2 ms 3360 KiB
sample_01.txt AC 4 ms 3460 KiB
sample_02.txt AC 2 ms 3352 KiB