社区讨论

关于这题贪心思想

P2831[NOIP 2016 提高组] 愤怒的小鸟参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lx2pbmj9
此快照首次捕获于
2024/06/06 11:32
2 年前
此快照最后确认于
2024/06/06 16:28
2 年前
查看原帖
我觉得这题满足贪心,但好像不是正解。
有不满足贪心的情况吗?
贪心代码如下:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=25;
const double eps=1e-8;
int t,n,m;
bool vis[N];
double x[N],y[N];
double geta(int a,int b) {
	return 1.0*(y[a]*x[b]-y[b]*x[a])/(x[a]*x[a]*x[b]-x[a]*x[b]*x[b]);
}
double getb(int i,double a) {
	return 1.0*(y[i]-a*x[i]*x[i])/x[i];
}
int check(double a,double b) {
	int res=0;
	for(int i=1; i<=n; i++) {
		if(abs(y[i]-(a*x[i]*x[i]+b*x[i]))<=eps) res++;
	}
	return res;
}
int main() {
	scanf("%d",&t);
	while(t--) {
		memset(vis,0,sizeof(vis));
		scanf("%d%d",&n,&m);
		for(int i=1; i<=n; i++) scanf("%lf%lf",&x[i],&y[i]);
		if(n==1) {
			printf("1\n");
			continue;
		}
		if(n==2) {
			double a=geta(1,2);
			if(a>0) printf("2\n");
			else printf("1\n");
			continue;
		}
		int now=n,ans=0;
		while(now) {
			if(now==1) {
				ans++;
				break;
			}
			if(now==2) {
				double a=geta(1,2);
				if(a>0) ans+=2;
				else ans+=1;
				break;
			}
			int maxx=-1;
			double ma,mb,a,b;
			for(int i=1; i<=n; i++) {
				if(vis[i]) continue;
				for(int j=i+1; j<=n; j++) {
					if(vis[j]) continue;
					a=geta(i,j);
					if(a>=-eps) continue;
					b=getb(i,a);
					int s=check(a,b);
					if(s>maxx) {
						ma=a;
						mb=b;
						maxx=s;
					}
				}
			}
			if(maxx==-1) {
				ans+=now;
				break;
			}
			for(int i=1; i<=n; i++) {
				if(abs(y[i]-ma*x[i]*x[i]-mb*x[i])<eps) {
					if(!vis[i]) now--;
					vis[i]=1;
				}
			}
			ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...