基本原则:
①满分1000000,判定分900000,连击分100000
②
③
④
根据以上四条,易得
①
②
③
④
用户输入分数和物量,由于只有Tap和Hold有good判定,需要输入good判定的最大数目GM(实际上这个不重要,因为good太多实践难度太高,随便输个数就行了)。
穷举法:外层举good,从最大到0;内层举perfect,从最大到最小,然后根据perfect和good数来计算maxcombo(程序里简写成combo)。游戏里显示的分数是经过四舍五入的,整数score代表的是区间,所以计算出的maxcombo应是一个左闭右开的范围,判断该范围内是否存在正整数(程序里用向上取整来判断),若该正整数存在且满足上述不等式②③,则该正整数为maxcombo值,输出这条结果,顺便计算一下acc。
完整代码:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
int score=-1,notes=-1,GM=-1;//GM是good的最大值
int p,g,combo,count=0;//p:perfect,g:good,combo:最大连击数
int pmin,pmax,cmin,cmax;
double acc;
while(!(score>=0&&score<=1000000)){//范围检测
cout <<"输入你想打的分数(0~1000000): ";
cin >> score;}
while(notes<=0)//范围检测
{cout <<"输入总物量:";
cin>>notes;}
while(!(GM>=0&&GM<=notes)){//范围检测
cout<<"输入tap+hold物量(good最大值)(0~"<<notes<<"):";
cin>>GM;
}
for(g=GM;g>=0;g--)//遍历good
{
pmin=ceil(notes*score/1000000.0-0.685*g);//向上取整
if(pmin<0)pmin=0;
pmax=notes-g;
for(p=pmax;p>=pmin;p--)//遍历perfect
{
cmin=ceil(notes*(score-0.5)/100000.0-9*p-5.85*g);
cmax=ceil(notes*(score+0.5)/100000.0-9*p-5.85*g);//计算maxcombo范围
for(combo=cmin;combo<cmax;combo++)
if(combo>=0 && combo<=(p+g) && (p+g-1)*(combo+1)<(notes*combo)){//筛选符合条件的整数maxcombo
acc=(p+0.65*g)/notes*100;
cout<<"perfect: "<<p<<",good: "<<g<<",bad+miss: "<<notes-p-g<<",maxcombo: "<<combo<<",acc:"<<fixed<<setprecision(2)<<acc<<"%"<<endl;
count++;}
}
}
if(count>0)
cout<<"共"<<count<<"种选择,推荐最后一种"<<endl;
else if(count==0)
cout<<"无法打出该得分"<<endl;
}
程序结果:(紧跟一下实事)

其余的结果经计算基本成立,但是个人引诱太菜难以亲自实践

当时觉得挺有意思就写了一下,没想到就火了。