(L3-012) Fruit Ninja (Denken + Aufzählen)

Themenlink: PTA | Programmgestaltung Experimentgestützte Lehrplattform

f

Analyse: Betrachten wir bei dieser Frage zunächst die besonderen Eigenschaften einer Geraden, die den Sinn der Frage erfüllt: Ob die Gerade l durch diese n Liniensegmente gehen kann und ob l durch keinen der unteren Endpunkte geht Liniensegment, dann können wir es verschieben, um es nach unten zu verschieben, bis es den unteren Endpunkt eines Liniensegments passiert. Zu diesem Zeitpunkt können wir nicht weiter nach unten verschieben, aber wir können uns um den unteren Endpunkt drehen, den wir passiert haben, bis wir den Endpunkt passiert haben Das heißt, wenn es eine Lösung gibt, können wir Finde eine andere Lösung konstruieren, damit sie durch die Endpunkte der beiden Liniensegmente verläuft (der obere und der untere Endpunkt spielen keine Rolle) , wodurch die Situation gelöst wird Die vier für die Antwort erforderlichen Koordinaten sind alle ganzzahlige Lösungen.

Was genau bedeutet das? Das heißt, wir wählen willkürlich ein Liniensegment aus, unter der Annahme, dass es eine gerade Linie gibt, die durch seinen unteren Endpunkt verläuft und die Bedeutung der Frage erfüllt, und verbinden uns dann mit den Endpunkten anderer Liniensegmente, um den Steigungsbereich des Ziels zu erhalten Gerade, da wir bereits einen Punkt kennen, durch den die Zielgerade geht, dann verbinde diesen Punkt und die beiden Endpunkte einer Strecke zu zwei Geraden Diese beiden Geraden entsprechen jeweils einer Steigung solange die Steigung ist der letzten Geraden zwischen den Steigungen der beiden Geraden liegt, kann sie durch das Liniensegment verlaufen, sodass wir den Bereich der Steigung der Ziellinie immer eingrenzen können, wenn der Maximalwert der Endsteigung größer als ist der minimale Wert der Steigung bedeutet, dass es eine Linie gibt, die der Bedeutung der Frage entspricht und durch den unteren Endpunkt des zu Beginn angenommenen Liniensegments verläuft . Da wir dabei den Neigungsbereich der Ziellinie verengen , bedeutet dies, dass der Endpunkt des aktuellen Liniensegments als ein von passierter Punkt verwendet werden kann, wenn das aktuelle Liniensegment, das wir durchqueren, den Neigungsbereich der Ziellinie verringert Ziellinie Der Steigungsbereich der beiden durch den Traversierungspunkt und das aktuelle Traversierungsliniensegment gebildeten Geraden umfasst den Steigungsbereich der Zielgeraden, hat also keinen Einfluss auf den Steigungsbereich der Zielgeraden während des Vorgangs nur die Endpunkte des Aktualisierungs-Zielintervalls aufzeichnen müssen Ja, am Ende, wenn die Intervalllänge der Ziellinie positiv ist, ausgeben, ansonsten den unteren Haltepunkt des nächsten Liniensegments weiter durchlaufen, bis a Zeile, die die Bedeutung der Frage erfüllt, gefunden wird.

Hier ist der Code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
const int N=1e4+10;
struct node{
	int x,y1,y2;
}p[N];
bool cmp(node a,node b)
{
	return a.x<b.x;
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		scanf("%d%d%d",&p[i].x,&p[i].y1,&p[i].y2);
	sort(p+1,p+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		double kmin=-0x3f3f3f3f,kmax=0x3f3f3f3f;
		double tmin,tmax;
		int tx,ty;
		bool flag=true;
		for(int j=1;j<=n;j++)
		{
			if(p[i].x==p[j].x) continue;
			if(i>j)
			{
				tmax=(double)(p[i].y2-p[j].y2)/(p[i].x-p[j].x);
				tmin=(double)(p[i].y2-p[j].y1)/(p[i].x-p[j].x);
				if(tmax<kmax)//斜率最大值被更新,记录更新斜率最大值的端点 
				{
					kmax=tmax;//斜率最小值被更新,记录更新斜率最小值的端点
					tx=p[j].x;ty=p[j].y2;//记录临界点坐标 
				}
				if(tmin>kmin)
				{
					kmin=tmin;
					tx=p[j].x;ty=p[j].y1;//记录临界点坐标 
				}
			}
			else
			{
				tmax=(double)(p[j].y1-p[i].y2)/(p[j].x-p[i].x);
				tmin=(double)(p[j].y2-p[i].y2)/(p[j].x-p[i].x);
				if(tmax<kmax)//斜率最大值被更新,记录更新斜率最大值的端点
				{
					kmax=tmax;
					tx=p[j].x;ty=p[j].y1;//记录临界点坐标 
				}
				if(tmin>kmin)//斜率最小值被更新,记录更新斜率最小值的端点
				{
					kmin=tmin;
					tx=p[j].x;ty=p[j].y2;//记录临界点坐标 
				}
			}
			if(tmin>kmax||tmax<kmin||kmax<kmin)//出现无解,也就是说不存在过第i条直线的下端点的直线满足题意 
			{
				flag=false;
				break;
			}
		}
		if(flag)
		{
			printf("%d %d %d %d",p[i].x,p[i].y2,tx,ty);
			break;
		}
	}
	return 0;
}

Ich denke du magst

Origin blog.csdn.net/AC__dream/article/details/123877235
Empfohlen
Rangfolge