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;
}
posted @ 2020-09-17 10:49  童年の波鞋  阅读(160)  评论(0编辑  收藏  举报