列表

详情


NC24123. [USACO 2011 Nov G]Cow Steeplechase

描述

Farmer John has a brilliant idea for the next great spectator sport: Cow Steeplechase! As everyone knows, regular steeplechase involves a group of horses that race around a course filled with obstacles they must jump over.
FJ figures the same contest should work with highly-trained cows, as long as the obstacles are made short enough.
In order to design his course, FJ makes a diagram of all the N (1 <= N <=250) possible obstacles he could potentially build. Each one is represented by a line segment in the 2D plane that is parallel to the horizontal or vertical axis. Obstacle i has distinct endpoints (X1_i, Y1_i) and (X2_i,Y2_i) . An example is as follows:

   --+-------
-----+-----
  ---+---     |
     |     |  |
   --+-----+--+-   |
     |     |  |  | |
     |   --+--+--+-+-
           |  |  | |
              |

FJ would like to build as many of these obstacles as possible, subject to the constraint that no two of them intersect. Starting with the diagram above, FJ can build 7 obstacles:

   ----------   
-----------
  -------     |
           |  |
           |  |    |
           |  |  | |
           |  |  | |
           |  |  | |
              |

Two segments are said to intersect if they share any point in common, even an endpoint of one or both of the segments.  FJ is certain that no two horizontal segments in the original input diagram will intersect, and that similarly no two vertical segments in the input diagram will intersect.
Please help FJ determine the maximum number of obstacles he can build.

输入描述

* Line 1: A single integer: N.
* Lines 2..N+1: Line i+1 contains four space-separated integers representing an obstacle: X1_i, Y1_i, X2_i, and Y2_i.

输出描述

* Line 1: The maximum number of non-crossing segments FJ can choose.

示例1

输入:

3
4 5 10 5
6 2 6 12
8 3 8 5

输出:

2

说明:

There are three potential obstacles. The first is a horizontal segment
connecting (4, 5) to (10, 5); the second and third are vertical segments
connecting (6, 2) to (6, 12) and (8, 3) to (8, 5).
The optimal solution is to choose both vertical segments.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 10ms, 内存消耗: 384K, 提交时间: 2020-10-19 20:48:21

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cctype>
#define INF 2000000000
using namespace std;
typedef long long ll;
int n,vis[255],match[255]={0},seg[255][4];
int X[255],Y[255],cx=0,cy=0;
bool mat[255][255]={0};
int read(){
	int f=1,x=0;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
	return f*x; 
}	
int Edmond(int S){
	for(int i=1;i<=cy;i++){
		if(mat[S][i]&&!vis[i]){
			vis[i]=1;
			if(!match[i]||Edmond(match[i])){
				match[i]=S;
				return 1;
			}
		}
	}
	return 0;
}
void init(){
	n=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=4;j++)
			seg[i][j]=read();
		if(seg[i][1]==seg[i][3]){
			Y[++cy]=i;//竖直 
			if(seg[i][2]>seg[i][4])
				swap(seg[i][2],seg[i][4]);
		}else {
			X[++cx]=i;//水平
			if(seg[i][1]>seg[i][3])
				swap(seg[i][1],seg[i][3]);
		} 
	}
	for(int i=1;i<=cx;i++)
		for(int j=1;j<=cy;j++)
			if(seg[Y[j]][1]>=seg[X[i]][1]&&seg[Y[j]][1]<=seg[X[i]][3]&&
                seg[X[i]][2]>=seg[Y[j]][2]&&seg[X[i]][2]<=seg[Y[j]][4])
                mat[i][j]=1;
}
void solve(){
	int ans=0;
	for(int i=1;i<=cx;i++){
		memset(vis,0,sizeof(vis));
		if(Edmond(i))ans++;
	}
	printf("%d\n",n-ans);
}
int main(){
	init();
	solve();
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 6ms, 内存消耗: 532K, 提交时间: 2020-10-20 14:33:00

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=255,MAXM=MAXN*MAXN;
struct Po
{
	int sx,sy,tx,ty;
}a[MAXN];
struct Edge
{
	int to,next;
}edge[MAXM];
int head[MAXN],match[MAXN],n,ans,tot=1;
bool vis[MAXN];
void addedge(int u,int v)
{
	edge[tot]=(Edge){v,head[u]};
	head[u]=tot++;
}
bool dfs(int u)
{
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(!vis[v])
		{
			vis[v]=1;
			if(!match[v]||dfs(match[v]))
			{
				match[v]=u;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%d%d%d%d",&a[i].sx,&a[i].sy,&a[i].tx,&a[i].ty);
	for(int i=1;i<=n;i++)
	{
		if(a[i].sx>a[i].tx)
		swap(a[i].sx,a[i].tx);
		if(a[i].sy>a[i].ty)
		swap(a[i].sy,a[i].ty);
	}
	for(int i=1;i<=n;i++)
	if(a[i].sx==a[i].tx)
	{
		for(int j=1;j<=n;j++)
		if(a[j].sy==a[j].ty&&a[j].sx<=a[i].sx&&a[j].tx>=a[i].sx&&a[i].sy<=a[j].sy&&a[i].ty>=a[j].sy)
		addedge(i,j);
	}
	for(int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof(vis));
		ans+=dfs(i);
	}
	printf("%d\n",n-ans);
	return 0;
}

上一题