b_pat_进制 & 爱丁顿数(二分+细节)
进制
给定一个正整数数对 N1,N2,并给出其中一个数字的进制,请你求出另一个数字在什么进制下,两数相等成立。
思路
约定字符串 a 是已知进制,b 是未知进制数;
二分枚举进制:一个数 b 如果是 k 进制,那么 b 的数字组成中必定不包含大于 k 的数字;所以二分的左边界可确定;右边界则是选一个拿不到的数;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//字符数字对应的数字
ll c2i(char c) {
if (c <= '9') return (ll) (c-'0');
return (ll) (c-'a'+10);
}
//k进制转10进制,枯了
ll k2ten(string& s, ll k) {
double radix=1;
ll ans=0, n=s.size();
for (ll i=n-1; i>=0; i--) {
if((double)ans + c2i(s[i])*radix > 1e18) return 1e18;
ans=ans+c2i(s[i])*radix, radix*=k;
}
return ans;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string a,b;
int tag, radix; cin>>a>>b>>tag>>radix;
if (tag==2) swap(a,b);
ll l=0, target=k2ten(a, radix), r=target+1;
for (char c : b) l=max(l, c2i(c)+1);
while (l<r) {
ll m=l+r>>1;
if (k2ten(b, m)<target) l=m+1;
else r=m;
}
if (k2ten(b, l)!=target) cout<<"Impossible";
else cout<<l;
cout<<'\n';
return 0;
}
复杂度分析
- Time:\(O(logn)\),
- Space:\(O(1)\),
爱丁顿数
“爱丁顿数” E ,即满足有 E 天骑车超过 E 英里的最大整数 E。
现给定某人 N 天的骑车距离,请你算出对应的爱丁顿数 E(≤N)
思路
简单二分...
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,A[N];
bool chk(int e) {
int c=0;
for (int i=0; i<n; i++) {
if (A[i]<=e) break;
c++;
}
return c>=e;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n;
for (int i=0; i<n; i++) cin>>A[i];
sort(A, A+n, [&](int a, int b){return a>b;});
int l=1, r=n, ans=0;
while (l<=r) {
int e=l+r>>1;
if (chk(e)) ans=e, l=e+1;
else r=e-1;
}
cout<<ans;
return 0;
}
看了下别人的解法,觉得nlogn的就像一坨...,是在佩服
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,A[N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n;
for (int i=1; i<=n; i++) cin>>A[i];
sort(A+1, A+n+1, [&](int a, int b){return a>b;});
int day=1, e=1;
while (e<=n && A[day]>e) day++, e++;
cout<<e-1;
return 0;
}