线性分类器
问题
输入两类数据点,若干个直线,判断直线是否可以将数据点分为两类。
思路
分类好判断,根据点与直线的关系,两种类型,一类代入等式后都小于零,另一类都大于零,则该直线可作为分类器。
用两个数组存储两类点,对于每根直线,进行判断。
首先判断两个数组的第一个元素,确定两个类型各自的正负情况,如果同号,则不继续,异号继续进行后续判断。
判断各组的点是否都同号,一旦不同,就在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