Link,第二场没打。
T1
\(100\),没挂分。
依题计算即可,\(O(1)\)。
#include<bits/stdc++.h>
using namespace std;
double n,a,b;
int main(){
//freopen("as01.in","r",stdin);
//freopen("as01.out","w",stdout);
cin>>n>>a>>b;
cout<<ceil(n/(a+b));
return 0;
}
T2
\(100 \to 45\),错因:没有特判 + check 写错。
二分 + 模拟即可,\(O(t \log k)\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,p,k;
bool check(int x){
int s=x,now=x;
while(now>=p){
s+=now/p;
now=now%p+now/p; //模拟时要加上剩余积分
}
return s>=k;
}
void sol(){
cin>>p>>k;
int l=-1,r=1e9+1;
if(p==1){ cout<<"1\n"; return; } //注意特判
if(k==0){ cout<<"0\n"; return; }
while(l+1<r){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid;
}
cout<<r<<'\n';
}
signed main(){
//freopen("as02.in","r",stdin);
//freopen("as02.out","w",stdout);
ios::sync_with_stdio(0);
cin>>t; while(t--) sol();
return 0;
}
T3
\(100 \to 36\),错因:使用字符串拼接被卡常。
直接依题模拟即可,\(O(\max(L,R))\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,l,r;
int lg[31];
void init(){
lg[0]=1;
for(int i=1;i<=6;i++) lg[i]=lg[i-1]*10;
}
void sol(){
cin>>l>>r;
int ans=0; init();
for(int i=l;i<=r;i++){
int x=i,p=lg[(int)log10(i)];
while(1){
x=x/10+(x%10)*p; //注意以后直接对数字运算完成构造,不要用字符串拼接
if(x==i) break;
else if(x>i&&l<=x&&x<=r) ans++;
}
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0);
cin>>t; while(t--) sol();
return 0;
}
总结:
-
\(300 \to 181\),依托勾史。
-
以后多注意问题考虑完整、思路清晰,并且注意常数。