题解:P11397 界分数
malinhao45 · · 题解
此题首先考虑贪心。这道题有两个操作:
- 分子分母都加
1 。 - 分子加
1 。
如果可以约分就约分。它要求的是
我们可以猜想一个结论:约分次数越多,操作数量越小。约分的公因数越小,操作数量越小。而每个数的因数都有
证明:如果要让分数的值变为
通过上述这些,我们可以迅速地写出一个模拟的代码:
#include<bits/stdc++.h>
#define mod 998244353
#define int long long
using namespace std;
int n;
signed main() {
cin>>n;
int ans=0;
for(int i=1; i<=n; i++) {
int t=i;
int cnt=1;
while(t!=1) {
t=(t+1)/2;
cnt++;
}
ans=ans%mod+cnt%mod;
}
cout<<ans%mod<<endl;
}
在赛时喜提了九十分的好成绩。
我发现最后全都超时了。考虑优化。
可以通过输出
在数据中,一共有 2 个 3 ,4 个 4 ,8 个 5 ,16 个 6 ,32 个 7 。
规律就是
我们可以得出代码:
#include<bits/stdc++.h>
#define mod 998244353
#define int long long
using namespace std;
int n;
signed main() {
cin>>n;
int ans=3;
n-=2;
int x=2;
int cc=3;
while(n-x>=0) {
n-=x;
ans=ans%mod+cc*x%mod;
ans%=mod;
x*=2;
cc++;
}
ans=ans%mod+n%mod*cc%mod;
cout<<ans%mod;
}
代码中
却还是九十分
因为
#include<bits/stdc++.h>
#define mod 998244353
#define int unsigned long long
using namespace std;
int n;
signed main() {
cin>>n;
int ans=3;
n-=2;
int x=2;
int cc=3;
long long m=n-x;
while(m>=0) {
n-=x;
ans=ans%mod+cc%mod*x%mod;
ans%=mod;
x*=2;
cc++;
m=n-x;
}
ans=ans%mod+n%mod*cc%mod;
cout<<ans%mod;
}
最后得到了100分。