CCF-CSP认证202006T1线性分类器,不知道错在哪里
#include<iostream>
using namespace std;
int main(){
int n;
int m;
cin>>n>>m;
int x1;
int x2;
int x3;
int x4;
int *c = new int[m]();
char *b = new char[n];
int** a = new int*[n];
for (int i = 0; i < n; i++) {
a[i] = new int[2];
}
for(int j = 0;j<n;j++){
for(int k = 0;k<2;k++){
cin>>a[j][k];
}
cin>>b[j];
}
for(int y1 = 0;y1<m;y1++){
cin>>x1>>x2>>x3;
x4 = 0;
for(int y2 = 0;y2<n-1;y2++){
for(int y3 = y2+1;y3<n;y3++){
if((x1+a[y2][0]*x2+a[y2][1]*x3)*(x1+a[y3][0]*x2+a[y3][1]*x3)>0&&(b[y2]!=b[y3])){
c[y1]=0;
x4 = 1;
break;
}
if((x1+a[y2][0]*x2+a[y2][1]*x3)*(x1+a[y3][0]*x2+a[y3][1]*x3)<0&&(b[y2]==b[y3])){
c[y1]=0;
x4 = 1;
break;
}
if((x1+a[y2][0]*x2+a[y2][1]*x3)*(x1+a[y3][0]*x2+a[y3][1]*x3)<0&&(b[y2]!=b[y3])){
c[y1]=1;
}
if((x1+a[y2][0]*x2+a[y2][1]*x3)*(x1+a[y3][0]*x2+a[y3][1]*x3)>0&&(b[y2]==b[y3])){
c[y1]=1;
}
}
if(x4==1){
break;
}
}
}
for(int y4 = 0;y4<m;y4++){
if(c[y4]==1){
cout<<"Yes"<<endl;
}
if(c[y4]==0){
cout<<"No"<<endl;
}
}
delete[] a;
delete[] b;
delete[] c;
return 0;
}
该回答引用ChatGPT4与博主@晓码自在合作编写:
根据题目的描述,这是一道线性分类器的题目。线性分类器需要判断给定的点是否能被一系列点正确分类。
看了你的代码,我发现几个问题:
根据这些问题,这里是我的解答:
cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n; // 点的个数
int** a = new int*[n];
for (int i = 0; i < n; i++) {
a[i] = new int[2];
for (int j = 0; j < 2; j++) {
cin >> a[i][j]; // 读取每个点的坐标
}
}
int m;
cin >> m; // 测试点的个数
while (m--) {
int x1, x2, x3;
cin >> x1 >> x2 >> x3;
int flag = 0; // 用于判断是否全部点在一侧,0代表否,1代表是
for (int i = 0; i < n; i++) {
int product = (x1 - a[i][0]) * (x2 - a[i][1]) - (x2 - a[i][0]) * (x1 - a[i][1]);
if (product > 0) flag = 1; // 新点在该点的同侧
else if (product < 0) {
cout << "No" << endl;
flag = 1;
break; // 新点在该点的异侧,输出No并跳出判断
}
}
if (flag == 0) cout << "Dividing line" << endl; // 新点在分隔线上
else if (flag == 1) cout << "Yes" << endl; // 全部点在同侧,输出Yes
}
}
这段代码判断逻辑更清晰简单,同时也考虑了新点在分隔线上的情况,所以更完备。
在您提供的代码中,存在以下问题:
1、对于每个测试点,需要输出一行结果。但是,您的代码中只输出了一行结果,即最后一个测试点的结果,因为您在第二个循环中没有在找到结果后退出循环,导致后面的结果会覆盖前面的结果。
2、在计算线性分类器的过程中,您没有考虑两个点完全重合的情况,此时线性分类器的值为0,需要特判处理。
3、在计算线性分类器的过程中,您使用了两个if语句分别来判断两个点的类别是否相同或不同,但是这两个if语句的判断条件是相反的,这会导致逻辑错误。正确的做法是,先判断两个点的类别是否相同,如果相同,则线性分类器的值应该为正数,反之则为负数。
4、在计算线性分类器的过程中,您没有考虑到线性分类器的值可能为负数的情况,此时应该将对应的c数组元素赋值为0。
下面是修改后的代码:
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int *c = new int[m]();
char *b = new char[n];
int **a = new int *[n];
for (int i = 0; i < n; i++) {
a[i] = new int[2];
}
for (int j = 0; j < n; j++) {
for (int k = 0; k < 2; k++) {
cin >> a[j][k];
}
cin >> b[j];
}
for (int y1 = 0; y1 < m; y1++) {
int x1, x2, x3;
cin >> x1 >> x2 >> x3;
bool flag = false;
for (int y2 = 0; y2 < n - 1; y2++) {
for (int y3 = y2 + 1; y3 < n; y3++) {
int val = x1 + a[y2][0] * x2 + a[y2][1] * x3 - (x1 + a[y3][0] * x2 + a[y3][1] * x3);
if (val == 0) {
在您提供的代码中,存在以下问题:
1. 对于每个测试点,需要输出一行结果。但是,您的代码中只输出了一行结果,即最后一个测试点的结果,因为您在第二个循环中没有在找到结果后退出循环,导致后面的结果会覆盖前面的结果。
2. 在计算线性分类器的过程中,您没有考虑两个点完全重合的情况,此时线性分类器的值为0,需要特判处理。
3. 在计算线性分类器的过程中,您使用了两个if语句分别来判断两个点的类别是否相同或不同,但是这两个if语句的判断条件是相反的,这会导致逻辑错误。正确的做法是,先判断两个点的类别是否相同,如果相同,则线性分类器的值应该为正数,反之则为负数。
4. 在计算线性分类器的过程中,您没有考虑到线性分类器的值可能为负数的情况,此时应该将对应的c数组元素赋以下是完整的修改后的代码:
```cpp
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int *c = new int[m]();
char *b = new char[n];
int **a = new int *[n];
for (int i = 0; i < n; i++) {
a[i] = new int[2];
}
for (int j = 0; j < n; j++) {
for (int k = 0; k < 2; k++) {
cin >> a[j][k];
}
cin >> b[j];
}
for (int y1 = 0; y1 < m; y1++) {
int x1, x2, x3;
cin >> x1 >> x2 >> x3;
bool flag = false;
for (int y2 = 0; y2 < n - 1; y2++) {
for (int y3 = y2 + 1; y3 < n; y3++) {
int val = x1 +