题解 P2645 【斯诺克】

· · 题解

在说题解之前,我不得不吐槽这个题的数据

非 常 水!

我开始手动模拟,把可能都列出来:

#include<bits/stdc++.h>
using namespace std;
int red=15;//红球初始值5个 
long long jia=0;//甲初始得分为0 
long long yi=0;//乙初始得分为0 
void add_score(int score,int i,int name){
    if(score==0){//如果分数为0 
        if(name==0)yi+=4;//给 方 分 
        else jia+=4;    //对 加
    }else if(score==1){//分数等于1,即打中红球 
        if(i%2){//如果是第奇数次打的话(按照规则打) 
            red--;//拿走红球 
            if(name==0)jia++;//给 己 分 
            else yi++;      //自 加 
        }else{//如果是第偶数次打的话(打了错误的球) 
            if(name==0)yi+=4;//给 方 分 
            else jia+=4;    // 对 加 
        }
    }else{//分数超过一 ,即打彩球 
        if(i%2&&red){//如果在第奇数次打的,且桌面上还有红球(即打了错误的球) 
            if(score>4){//如果分数大于四 
                if(name==0)yi+=score;//给 方 分
                else jia+=score;    // 对 加 
            }else{//分数不大于四 
                if(name==0)yi+=4;//给 方 分
                else jia+=4;    // 对 加 
            }
        }else{//没犯规 
            if(name==0)jia+=score;//给 己 分
            else yi+=score;      //自 加 
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    cin>>n>>m;  
    for(int i=1;i<=n;i++){
        int ball;
        cin>>ball;
        add_score(ball,i,0);//计算分数(甲) 
    }   
    for(int i=1;i<=m;i++){
        int ball;
        cin>>ball;
        add_score(ball,i,1);//计算分数(乙) 
    }
    cout<<jia<<" "<<yi<<endl;
    return 0;
}

如此详细的代码,竟然只有40分!(而且不给数据!)

调了n小时,好像没啥毛病???

我开始了深入探究:

1.斯诺克

    ——了解斯诺克台球

了解斯诺克的童鞋一定知道:斯诺克有1个白球,15个红球和6个彩球(黄、绿、咖啡、蓝、粉、黑)共22个球。

在不违反规则的情况下,红球入洞不捡;彩球入洞照样捡;和题目中给的一样。

这里斯诺克的规则不在详述。

2.题意

    ——了解题意

打完一个红球必须打彩球,红球没了直接打彩球,否则按犯规处理(给对方加相应分)。不打也给对方加四分;如果老老实实按规矩打,自己加相应分。

3.思路&代码

     ——好像,没那么复杂

先给大家看看AC代码:

#include<bits/stdc++.h>
using namespace std;
long long jia=0;//甲初始得分为0 
long long yi=0;//乙初始得分为0 
void add_score(int score,int i,int name){
    if(score==0){//如果分数为0 
        if(name==0)yi+=4;//给 方 分 
        else jia+=4;    //对 加
    }else if(score==1){//分数等于1,即打中红球 
        if(name==0)jia++;//给 己 分 
        else yi++;      //自 加 
    }else{//分数超过一 ,即打彩球 
        if(name==0)jia+=score;//给 己 分
        else yi+=score;      //自 加 
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    cin>>n>>m;  
    for(int i=1;i<=n;i++){
        int ball;
        cin>>ball;
        add_score(ball,i,0);//计算分数(甲) 
    }   
    for(int i=1;i<=m;i++){
        int ball;
        cin>>ball;
        add_score(ball,i,1);//计算分数(乙) 
    }
    cout<<jia<<" "<<yi<<endl;
    return 0;
}

比较原来的代码,发现:

题目有bug:

  1. 无需考虑打中的是什么球,管你怎么打,只要打中球了,直接给自己加分。(可以无视规则)

  2. 所谓的“强大的特判”无非就是考虑没打中球的情况,对于这个,打过台球的人都知道。(多次强调却没有实际意义的特判)

  3. 老实模拟的人反而错了(比如我,40分)

综上所述,我只能得出题目或数据有问题。(而且这哪是斯诺克啊!明明就是在打那些业余选手都会的普通台球!)希望管理员能重新修改此题的数据。

求通过