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; }
Comments
(Participate in the discussion)
Comments
发现3条评论
repostone
2019年05月13日 17:13获取中...
非技术的路过。
repostone
2019年05月11日 17:28获取中...
居然研究这个。
A/B
博主2019年05月13日 13:30获取中...
@repostone其实很简单的,就一条神经元,而且还没有用到反向传播算法。。。 :evil: