HDU - 6590 Code (模擬?

HDU - 6590 Code (模擬?

description
(題目套了個AI的背景hhh,不過維數只有2)
y=sign(x1w1+x2w2+b)y=sign(x1*w1+x2*w2+b)
sign(t)={1t>00t=01t<0 sign(t)=\begin{cases} 1 & t>0 \\ 0 & t=0 \\ -1 & t<0 \end{cases}
給定x1,x2,yx1,x2,y(PPS:題目給的y只會是1或者-1)
問是否存在w1,w2,bw1,w2,b滿足所有的“樣本”

solution
(最開始沒看到這個sign。。寫了一個高斯消元着實丟人
因爲題目給的y是1或者-1
我們就可以動點腦筋
假如有yi=1yj=1y_i=1 並且 y_j=-1我們就可以推導出
sign(x1iw1+x2iw2+b)>sign(x1jw1+x2jw2+b) sign(x1_i*w1+x2_i*w2+b)>sign(x1_j*w1+x2_j*w2+b)
x1iw1+x2iw2+b>x1jw1+x2jw2+bx1_i*w1+x2_i*w2+b>x1_j*w1+x2_j*w2+b
x1iw1+x2iw2>x1jw1+x2jw2x1_i*w1+x2_i*w2>x1_j*w1+x2_j*w2
x1iw1x1jw1>x2jw2x2iw2x1_i*w1-x1_j*w1>x2_j*w2-x2_i*w2
(x1ix1j)w1>(x2jx2i)w2(x1_i-x1_j)*w1>(x2_j-x2_i)*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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章