PTA 7-66 秀恩爱分得快 题解
PTA 7-66 秀恩爱分得快 题解
测试点三让我改了两天代码!!!!!
但是最后我还是没能完全确定测试点三是为什么“段错误”
测试点三错误的可能猜测:
可能有一张图片有且仅有一个人,且他(她)是情侣之一
一道模拟题,没什么特别的值得探讨的思维点,需要注意的坑点有:
- 出现 \(-0\) 的情况如何处理
- 最后给出情侣时男女方给定顺序不定
- 如果男女方都不在任一一张图片里边如何处理
直接贴满分屎山代码了:
//cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m;
const double eps = 1e-3;
int flag;
struct nodea{
int id;
double val;
}na[10010];
bool operator < (nodea x, nodea y){
if(abs(abs(x. val) - abs(y.val)) < eps) return abs(x.id) < abs(y.id);
else return x.val > y.val;
}
struct nodeb{
int id;
double val;
}nb[10010];
bool operator < (nodeb x, nodeb y){
if(abs(abs(x. val) - abs(y.val)) < eps) return abs(x.id) < abs(y.id);
else return x.val > y.val;
}
vector <int> vc[1010];
int a, b;
inline long long read(){
char readch=getchar(); ll readtmp=0;
ll readflag=1;
while(readch<'0' || '9'<readch){if(readch=='-')readflag=-1;readch=getchar();}
while('0'<=readch && readch<='9'){readtmp=readtmp*10+readch-'0';readch=getchar();}
if(readflag == -1 && readtmp == 0) return -1010;// 0 -> man
return readtmp*readflag;
}
bool check(){ // 检查,是否只需要输出(a, b)
if(na[0].val == 0 && nb[0].val == 0) return 1;// 如果a, b, 都不在任一照片里,那么a, b, 最大亲密值肯定也是0
bool flaga = 0, flagb = 0;
if(na[0].id == b) flaga = 1; // a的最大亲密对象是b
if(nb[0].id == a) flagb = 1;
int x = 0;
//由于最大值可能会有重复,而operator排序无法保证在前的是情侣对方,我们需要一个个找
while(abs(na[x++].val - na[x].val) < eps){
if(na[x].id == b) flaga = 1;
}
x = 0;
while(abs(nb[x++].val - nb[x].val) < eps){
if(nb[x].id == a) flagb = 1;
}
return flaga && flagb;
}
void print_only_ab(){
if(a == 0){
if(!flag) printf("-%d %d", a, b);
else printf("%d -%d", b, a);
}
else {
if(!flag) printf("%d %d", a, b);
else printf("%d %d", b, a);
}
}
void printa(){
int x = 0;
if(a == 0) printf("-%d %d\n", a, na[0].id);
else printf("%d %d\n", a, na[0].id);
while(abs(na[x++].val - na[x].val) < eps){
if(a == 0) printf("-0 %d\n", na[x].id);
else printf("%d %d\n", a, na[x].id);
}
}
void printb(){
int x = 0;
if(nb[0].id!=0) printf("%d %d\n", b, nb[0].id);
else printf("%d -0\n", b);
while(abs(nb[x++].val - nb[x].val) < eps){
if(nb[x].id!=0) printf("%d %d\n", b, nb[x].id);
else printf("%d -0\n", b);
}
}
void pre(){ // 预处理
cin >> n >> m;
for(int k=1; k<=m; k++){
int x = read();
for(int i=1; i<=x; i++){
int y = read();
vc[k].push_back(y);
}
}
cin >> a >> b;
if(b < a) {
swap(a, b); // a->women ; b-> man
flag = 1;
}
}
void work(){
// 记录a, b, 对每一个人的亲密值
for(int i=1; i<=m; i++){
int len = vc[i].size();
if(find(vc[i].begin(), vc[i].end(), a) != vc[i].end()){
for(int j=0; j < len; j++){
int x = vc[i][j];
//如果男方是0,直接记录就行,如果女方是0,那她已经标记为-1010了,不会影响结果统计
if(x >= 0) {
na[x].val += 1.0/len;
na[x].id = x;
}
}
}
if(find(vc[i].begin(), vc[i].end(), b) != vc[i].end()){
for(int j=0; j< len; j++) {
int x = vc[i][j];
if(x < 0 && x!=-1010) {
x = abs(x);
nb[x].val += 1.0/len;
nb[x].id = -1*x;
}
else if(x == -1010){
nb[0].val += 1.0/len;
nb[0].id = 0;
}
}
}
}
}
int main(){
pre();
if(a == 0) a = -1010;
// 显然我们需要处理 a==-0 的情况,此时 b>0 一定成立,那么 a<b 一定成立。所以不会出现pre()中swap会影响答案的现象
//于是我们把-0替换为-1010来避免0与-0的混乱
work();
sort(na, na+n);
sort(nb, nb+n);
if(a == -1010) a=0;
if(check()){
print_only_ab();
return 0;
}
if(!flag){
printa();
printb();
}
else {
printb();
printa();
}
return 0;
}
反思
对于模拟题,我们需要多采用模块化编称,多组装成接口的形式调用,一个是可以使逻辑明显,一个是可以简化代码,最好是第一遍写的时候就有严谨与模块化的意识,并自大至小,由框架到细节,想清楚再动键盘,一旦写完一遍,后面改起来会非常折磨

浙公网安备 33010602011771号