https://www.luogu.org/problemnew/show/P3691

题目大意:

给你一堆点,每个点有个属性,要么是1要么是-1.

这些属于1和-1类的点分布在x∈[0,100],y∈[0,100]的平面上,

然后再给你一堆点,同样具有要么是1要么是-1的属性,问你这些额外的点是属于1还是-1,

保证对于所有的点都存在一条直线,可以把不同属性的点分开两边,

由于琪露诺太笨了存在0.1%的概率,一开始输入的点的属性是错误的。

你输出的答案,对于每个测试点正确率高于80%就能通过。(有的测试点是30%)

做法:

一般的凸包是过不了的,因为输入数据有错。

正解是神经网络(只有一根神经元那种)

跟着下面文章的思路走就懂了,其实对于这道题,就只是要调整一个线性多项式函数的系数。。

https://www.jianshu.com/p/d7189cbd0983?from=groupmessage

 

我的神经网络(元)还是很捞的,因为时间太长。。开O2才能A掉不然会T,然后正确率。。其实还可以8,最低有百分之80+。

这也是我的神经网络入门!没有什么高大上的反向传播啥的,只是普普通通的迭代。。

但A掉这题成就感蛮大的。。毕竟跟神经网络沾边。

AC快乐就VANS了。省赛加油

#include<bits/stdc++.h>
using namespace std;
double wx, wy, b;
double dx, dy, db;
double learnrate = 0.3;
double dset[100000][3];
void init(){
	wx = 0.5;
	wy = 0.5;
	b = 1.0;
}

void train(double x, double y, int t){
	double res;
	res = wx * x + wy * y + b;
	res = t - tanh(res);
	dx += learnrate * (res * x);
	dy += learnrate * (res * y);
	db += learnrate * (res);
		
}
int main(){
	int n, m, p;
	double x, y;
	init();
	int t;
	cin >> n >> m >> k;
	for (int i = 0; i < n; i++)
		cin >> dset[i][0] >> dset[i][1] >> dset[i][2];
	for (int k = 0; k < 1000; k++){
		dx = 0;
		dy = 0;
		db = 0;
		for (int i = 0; i < n; i++){
			train(dset[i][0], dset[i][1], dset[i][2]);
		}
		wx += dx;
		wy += dy;
		b += db;

	//cout << wx << "," << wy << ":" << b << endl;
	//system("pause");
		//cout << wx << "," << wy << ":" << b << endl;
	}
	for (int i = 0; i < m; i++){
		cin >> x >> y;
		double ge;
		ge = tanh(wx * x + wy * y + b);
		//cout << ge <<  endl;
		if (ge <= 0) cout << "-1" << endl;
		if (ge > 0) cout << "1" << endl;
	}