csp 20-06-1 线性分类器 & 2稀疏向量

本文介绍了如何使用线性分类器判断给定数据点是否能被直线划分为两类,并详细描述了使用数组和map结构处理稀疏向量以计算内积的方法。作者在过程中分享了编程过程中的思考和修正错误的过程。
摘要由CSDN通过智能技术生成
线性分类器
问题

输入两类数据点,若干个直线,判断直线是否可以将数据点分为两类。

思路

分类好判断,根据点与直线的关系,两种类型,一类代入等式后都小于零,另一类都大于零,则该直线可作为分类器。
用两个数组存储两类点,对于每根直线,进行判断。
首先判断两个数组的第一个元素,确定两个类型各自的正负情况,如果同号,则不继续,异号继续进行后续判断。
判断各组的点是否都同号,一旦不同,就在ans[]数组记录0,break,结束判断。用一个flag作为判断有无出现异号的状况,如果两组都顺利通过,最后flag为1,则对ans[]赋值为1,continue,结束此次循环。(一开始写成break,真的蠢货,以后要记得。)

输入

9 3
1 1 A
1 0 A
1 -1 A
2 2 B
2 3 B
0 1 A
3 1 B
1 3 B
2 0 A
0 2 -3
-3 0 2
-3 1 1
#include <iostream>
#include <vector>

using namespace std;

int main() {
	int n, m;
	cin >> n >> m; //n 个点 m条线
	int x, y;
	char type;
	int num1 = 0, num2 = 0;
	vector<vector<int> > A(n, vector<int>(2));
	vector<vector<int> > B(n, vector<int>(2));
	for(int i = 0; i < n; i++) {
		cin >> x >> y >> type;
		if(type == 'A') {
			A[num1][0] = x;
			A[num1][1] = y;
			num1++;
		} else if(type == 'B') {
			B[num2][0] = x;
			B[num2][1] = y;
			num2++;
		}
	}
	vector<int> ans(m);
	int k0, k1, k2;
	int temp, temp1, temp2;
	int flag;
	for(int i = 0; i < m; i++) {
		cin >> k0 >> k1 >> k2;
		temp1 = k0 + k1 * A[0][0] + k2 * A[0][1];
		temp2 = k0 + k1 * B[0][0] + k2 * B[0][1];
		flag = 1;
		if((temp1 > 0 && temp2 < 0)) {
			for(int j = 1; j < num1; j++) {
				temp = k0 + k1 * A[j][0] + k2 * A[j][1];
				if(temp < 0) {
					ans[i] = 0;
					flag = 0;
					break;
				}
			}
			if(flag) {
				for(int j = 1; j < num2; j++) {
					temp = k0 + k1 * B[j][0] + k2 * B[j][1];
					if(temp > 0) {
						ans[i] = 0;
						flag = 0;
						break;
					}
				}
			}
			if(flag) {
				ans[i] = 1;
				continue;
			}
		} else if((temp1 < 0 && temp2 > 0)) {
			for(int j = 1; j < num1; j++) {
				temp = k0 + k1 * A[j][0] + k2 * A[j][1];
				if(temp > 0) {
					ans[i] = 0;
					flag = 0;
					break;
				}
			}
			if(flag) {
				for(int j = 1; j < num2; j++) {
					temp = k0 + k1 * B[j][0] + k2 * B[j][1];
					if(temp < 0) {
						ans[i] = 0;
						flag = 0;
						break;
					}
				}
			}
			if(flag) {
				ans[i] = 1;
				continue;
			}
		}
		ans[i] = 0;
	}

	for(int i = 0; i < m; i++) {
		if(ans[i] == 1)
			cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}
get

其实没有break,只是这样省时间,最后一个break也可以没有的,但是觉得顺手就写了,觉得能少往下执行一行?,嗷之前好像是有另外的处理,这次的代码出问题,就是在跳出循环后的处理乱了,最后终于理清思路,但是break和continue用错了,长记性,用break的时候,看好是在哪个循环里。

稀疏向量
问题

给出两个稀疏向量,计算内积。

思路

使用map存储u、v,遍历u,拿着key去v里面找有没有这个键,存在的话,两个值相乘,累计起来,等到最后的值。
第一次提交,60分,检查思路没问题,发现是数据类型问题,题目说,值得绝对值小于10e5,那么乘积得话,就会大于10e9,所以使用long long 类型保存乘积。这题n没有用,起一个限制a , b 的作用?

1000000000 3 4
4 5
7 -3
10 1
1 10
4 20
5 30
7 40
#include <iostream>
#include <map>

using namespace std;

int main() {
	int n, a, b;
	map<int,int> u, v;
	cin >> n >> a >> b;
	int key, value;
	for(int i = 0; i < a; i++) {
		cin >> key >> value;
		u[key] = value;
	}
	for(int i = 0; i < b; i++) {
		cin >> key >> value;
		v[key] = value;
	}
	long long sum = 0;

	for(map<int,int>::iterator it = u.begin(); it != u.end(); ++it) {
		if(v.count(it->first) == 1) {
			sum += v[it->first] * it->second;
		}
	}
	cout << sum << endl;
	return 0;
}
get

发现还是没有记住map的使用
再次记忆

//定义
map<keyType, valueType> myMap
//赋值
map[key] = value
//查找
if(myMap.count(key) > 0)
//遍历
for(map<>::iterator it = myMap.begin(); it != myMap.end(); ++it)
//访问键和值
it->first
it->second

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值