刷题统计:蓝桥杯2022年第十三届省赛真题-刷题统计 - C语言网 (dotcpp.com)
粗去粗心,做这道题总体来看犯了三次错误。
第一个错误:第一次自己做出来,定义了三个函数,不断在weekend函数,workday函数传参跳跃,直至算出最终天数,但是内存超限61。
第二个错误:忽略了a,b,n,总做题数和总天数的范围(应该用long long int).修改过后变成内存超限71,没想到这个是能扣10分的。
最终修改后的错误代码如下:
#include<iostream>
using namespace std;
#define ll long long int
ll day=0,num=0;
void workday(ll a,ll b,ll n)
{
void weekend(ll a,ll b,ll n);
for(int i=0;i<5;i++){
if(num>=n)
return;
else
num+=a;
day++;
}
weekend(a,b,n);
}
void weekend(ll a,ll b,ll n)
{
void workday(ll a,ll b,ll n);
for(int i=0;i<2;i++){
if(num>=n)
return;
else
num+=b;
day++;
}
workday(a,b,n);
}
int main()
{
ll a,b,n;
cin>>a>>b>>n;
workday(a,b,n);
cout<<day;
return 0;
}
最终还是内存超限,所以应该采取更加优化的方法。我看了题解后找到最简洁易懂的方法,题解中说道:
思考一下我们循环的目的是什么?不就是为了从第1天算到答案所需要的那一天,然后一星期一星期的循环,那我们直接利用除法和求余就可以代替循环的过程对吧.
没错,可以用除法和求余代替不必要的循环。
我理解了题解后自己敲了一遍,出现了第三个错误:
#include<iostream>
using namespace std;
int main()
{
long long int a,b,n,week=0,left=0,cnt=0;
cin>>a>>b>>n;
week=n/(a*5+b*2);//完全周
left=n%(a*5+b*2);//最后一周剩余题量
while(left>0){
cnt++;
if(left<a)break;
if(left>5*a)
left-=b;
else
left-=a;
}
cout<<(week*7+cnt);
return 0;
}
这次是答案错误90,很接近正确答案了。我对比了下题解给出的答案正确100的代码,发现是循环最后一周来计算cnt(也就是最后一周的做题天数)的地方出现了问题,我将left(剩余题数)减题数的顺序为:如果left大于5*a则一天一天地减b来增加cnt,为什么错误呢?这里假设left=a*5+1,如果按上面的代码,则会把此时当作星期六来先把left减去2,但实际上是先过了周一至周五后才在周六做了最后一道题,所以这样就会造成混乱。
所以应该按照周一至周日的顺序来增加天数,并减少题数。正确代码:
#include<iostream>
using namespace std;
int main()
{
long long a, b, n, cnt = 0;
cin >> a >> b >> n;
long long week = 0; //计算有几个整个周都在刷题
long long left = 0; //最后一个周剩余题量
week = n / (a * 5 + b * 2);
left = n % (a * 5 + b * 2);
while(left > 0){ //最后一个周进行循环
cnt++;
if(cnt<=5)
left-=a;
else
left-=b;
}
cout << cnt + week * 7;
return 0;
}