HDU - 6590 Code (模拟?
description
(题目套了个AI的背景hhh,不过维数只有2)
y
=
s
i
g
n
(
x
1
∗
w
1
+
x
2
∗
w
2
+
b
)
y=sign(x1*w1+x2*w2+b)
y=sign(x1∗w1+x2∗w2+b)
s
i
g
n
(
t
)
=
{
1
t
>
0
0
t
=
0
−
1
t
<
0
sign(t)=\begin{cases} 1 & t>0 \\ 0 & t=0 \\ -1 & t<0 \end{cases}
sign(t)=⎩⎪⎨⎪⎧10−1t>0t=0t<0
给定
x
1
,
x
2
,
y
x1,x2,y
x1,x2,y(PPS:题目给的y只会是1或者-1)
问是否存在
w
1
,
w
2
,
b
w1,w2,b
w1,w2,b满足所有的“样本”
solution
(最开始没看到这个sign。。写了一个高斯消元着实丢人
因为题目给的y是1或者-1
我们就可以动点脑筋
假如有
y
i
=
1
并
且
y
j
=
−
1
y_i=1 并且 y_j=-1
yi=1并且yj=−1我们就可以推导出
s
i
g
n
(
x
1
i
∗
w
1
+
x
2
i
∗
w
2
+
b
)
>
s
i
g
n
(
x
1
j
∗
w
1
+
x
2
j
∗
w
2
+
b
)
sign(x1_i*w1+x2_i*w2+b)>sign(x1_j*w1+x2_j*w2+b)
sign(x1i∗w1+x2i∗w2+b)>sign(x1j∗w1+x2j∗w2+b)
x
1
i
∗
w
1
+
x
2
i
∗
w
2
+
b
>
x
1
j
∗
w
1
+
x
2
j
∗
w
2
+
b
x1_i*w1+x2_i*w2+b>x1_j*w1+x2_j*w2+b
x1i∗w1+x2i∗w2+b>x1j∗w1+x2j∗w2+b
x
1
i
∗
w
1
+
x
2
i
∗
w
2
>
x
1
j
∗
w
1
+
x
2
j
∗
w
2
x1_i*w1+x2_i*w2>x1_j*w1+x2_j*w2
x1i∗w1+x2i∗w2>x1j∗w1+x2j∗w2
x
1
i
∗
w
1
−
x
1
j
∗
w
1
>
x
2
j
∗
w
2
−
x
2
i
∗
w
2
x1_i*w1-x1_j*w1>x2_j*w2-x2_i*w2
x1i∗w1−x1j∗w1>x2j∗w2−x2i∗w2
(
x
1
i
−
x
1
j
)
∗
w
1
>
(
x
2
j
−
x
2
i
)
∗
w
2
(x1_i-x1_j)*w1>(x2_j-x2_i)*w2
(x1i−x1j)∗w1>(x2j−x2i)∗w2
这个式子应该永远成立
然而两个变量不好处理于是乎根据高中数学导数题的常用套路,左右两边同时除以w1(记得特殊考虑w1=0的情况!)
然后就是解不等式组 看看有没有解喽
(有人可能会觉得只有一个方向肯定有解啊?)
(一定要小心处理乘除负数导致不等号方向改变的情况!)
code
#include<bits/stdc++.h>
typedef long long LL;
const int oo=0x3f3f3f3f;
const int N=110;
const int MOD=1e9+7;
using namespace std;
int read(){
int f=1,s=0;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())s=s*10+c-'0';
return f*s;
}
int x1[N],x2[N],y[N];
bool work(){
int n=read();
for(int i=0;i<n;i++){
x1[i]=read();
x2[i]=read();
y[i]=read();
}
//w1>0
double L=-1LL<<31,R=1LL<<31;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(i==j)continue;
if(y[i]==1&&y[j]==-1){
int fenmu=x2[j]-x2[i];
int fenzi=x1[i]-x1[j];
if(fenmu==0)continue;
if(fenmu<0)L=max(L,1.0*fenzi/fenmu);
else R=min(R,1.0*fenzi/fenmu);
}
}
// printf("%.3lf %.3lf\n",L,R);
if(L<=R)return true;
//w1==0
L=-1LL<<31,R=1LL<<31;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(i==j)continue;
if(y[i]==1&&y[j]==-1){
int fenmu=x2[j]-x2[i];
int fenzi=0;
if(fenmu==0)continue;
if(fenmu>0)L=max(L,1.0);
else R=min(R,-1.0);
}
}
//printf("%.3lf %.3lf\n",L,R);
if(L<=R)return true;
//w1<0
L=-1LL<<31,R=1LL<<31;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(i==j)continue;
if(y[i]==1&&y[j]==-1){
int fenmu=x2[j]-x2[i];
int fenzi=x1[i]-x1[j];
if(fenmu==0)continue;
if(fenmu>0)L=max(L,1.0*fenzi/fenmu);
else R=min(R,1.0*fenzi/fenmu);
}
}
// printf("%.3lf %.3lf\n",L,R);
if(L<=R)return true;
return false;
}
int main(){
int T=read();
for(int i=1;i<=T;i++){
if(work()==true)printf("Successful!\n");
else printf("Infinite loop!\n");
}
return 0;
}