众所周知,

double 容易被 卡精度

在这道题中,好巧不巧就有一个 double 型数据——充值返点倍率 MM

此题的要求很简单——

NN 元钱购买点数,再出售点数来获得 利润与经验

于是,就有以下的 暴力程序

#include<bits/stdc++.h>
using namespace std;
int t,n;
double m;
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		int ans=0,green,red;
		while(n)
		{
			green=min(10000,int(n*100*(m-1.0)));
			red=100*n;
			n=0;
			ans+=int(green/10);
			ans+=int(red/10);
//			printf("green=%d red=%d ans=%d n1=%d ",green,red,ans,n);
			n+=int(red/200);
//			printf("n2=%d\n",n);
		}
		printf("%d\n",ans);
	}
	return 0;
}

然而,

我们获得了 0分的 成绩

反思一下,

应该是被 卡精度(废话

我们知道,绿点的计算公式为:

min(10000,a×100×(M1))\min(10000,a×100×(M−1))

我们化简一下这个式子,即:

min(10000,100×a×M100×a)\min(10000,100×a×M-100×a)

又因为主人公会将手上的钱全部花光,所以有:

min(10000,100×N×M100×N)\min(10000,100×N×M-100×N)

可是,代入这个式子真的能 AC\green{AC} 这道题吗?

我可以肯定地告诉你:能!

我们让 MM 乘上 100100,并且题目保证,

MM 是一位小数

于是,MM 脱胎换骨,成为了 int 类型!

以下,就是此题的 正解代码

#include<bits/stdc++.h>
using namespace std;
int t,n;
double m;
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		int ans=0,green,red;
		while(n)
		{
			green=min(10000,int(m*100*n-100*n));//此为修改处
			red=100*n;
			n=0;
			ans+=int(green/10);
			ans+=int(red/10);
//			printf("green=%d red=%d ans=%d n1=%d ",green,red,ans,n);
			n+=int(red/200);
//			printf("n2=%d\n",n);
		}
		printf("%d\n",ans);
	}
	return 0;
}