一道C++问题——擦数游戏

擦数游戏

总时间限制: 5000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB
描述
  有人在黑板上从 1 开始写出一组连续的自然数,然后擦去其中的一个数 k,其余的数的平均值为 a+c/b(繁分式)。试编写程序求出被擦去的数 k。例如:在黑板上写出 1,2,.69 之后把数 7 擦去而得到的其余的 68 个数的平均值为 35+7/17。

输入
输入仅一行包含以空格分隔的三个整数 a、b、c(a,b,c≤100)。

输出
输出为擦去的数 k,若对于输入的三个数无解,则输出“NO”。

样例输入
【样例 1】
35 17 7
【样例 2】
1 3 2
样例输出
【样例 1】
7
【样例 2】
NO

这道题目我一直只有80,求高人看看哪里有问题,如果我代码实在太难看直接贴代码讲解一下也可以,谢谢!

#include<iostream>
#include<cmath>
using namespace std;
int gcd(int x,int y){
    int t;
    while(y){
        t=y;y=x%y;x=t;
    }
    return x;
}
int sum(int x){
    return x*(x+1)/2;
}
long long a,b,c,n,k;
int main(){
    cin>>a>>b>>c;
    long long Gcd=gcd(b,c),Sum,Tmp,l;
    b/=Gcd;c/=Gcd;
    n=b;
    while(1){
        Sum=sum(n+1);
        Tmp=a*n+n/b*c;
        if(Sum>Tmp && Sum<Tmp+n){
            k=Sum-Tmp;
            l=n+1;
            if(l*(l+1)/2!=Sum||(l-1)%b!=0||abs((n+2)/2-(a+c/b))!=k/(n+1)){cout<<"NO";return 0;}
            else {cout<<k;return 0;}
        }
        n+=b;
    }
}

我不用看都知道你是a+c/b这里出了问题
c/b是分数,你不可以真的除完变成小数来算,小数精度有限会出现误差
你应该通分,把a+c/b变成(a*b+c)/b,这里也不要直接除,而是把b移到等号右面去,同时把等号右边的平均值的分母移到左边来
也就是说,本来你想判断(a*b+c)/b是否等于68项和/68
现在你需要判断的是(a*b+c)*68==68项和*b,不要让式子里出现除法