HDU - 6590 Code (模拟?

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(x1w1+x2w2+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)=101t>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=1yj=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(x1iw1+x2iw2+b)>sign(x1jw1+x2jw2+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 x1iw1+x2iw2+b>x1jw1+x2jw2+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 x1iw1+x2iw2>x1jw1+x2jw2
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 x1iw1x1jw1>x2jw2x2iw2
( 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 (x1ix1j)w1>(x2jx2i)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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值