1. 程式人生 > >Codeforces 1062 - A/B/C/D/E - (Undone)

Codeforces 1062 - A/B/C/D/E - (Undone)

連結:http://codeforces.com/contest/1062


A - Prank - [二分]

題意:

給出長度為 $n(1 \le n \le 100)$ 的陣列 $a[1 \sim n]$,且滿足 $1 \le a[1] < a[2] < \cdots < a[n] \e 1000$。現在JATC要擦掉其中一段連續的數字,但是要求能夠通過剩餘的其他數字,推斷出擦掉的數字是什麼。求JATC能擦掉的最長長度。

題解:

其實 $O(n)$ 就可以求出能擦掉的最長長度,但是因為 $n$ 比較小,懶得考慮太多,直接二分吧……

二分能擦掉的長度,對於固定的長度,$O(n)$ 列舉始末點判斷能否擦除即可。

AC程式碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
int n,a[maxn];
bool judge(int k)
{
    for(int i=1,j=i+k-1;j<=n;i++,j++) {
        if(a[j+1]-a[i-1]==k+1) return 1;
    }
    return 0;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    a[
0]=0, a[n+1]=1001; int l=0, r=n; while(l<r) { int mid=(l+r+1)/2; if(judge(mid)) l=mid; else r=mid-1; } cout<<l<<endl; }

 


B - Math - [數學題]

題意:

給出一個正整數 $n(1 \le n \le 1e6)$,你現在可以對 $n$ 進行任意多次乘以正整數 $x$ 或者開方(當結果為整數時才允許開方)操作。

求結果最小為多少,達到這個結果最少進行多少次操作。

題解:

分解質因數 $n = {p_1}^{a_1}{p_2}^{a_2} \cdots {p_k}^{a_k}$,顯然最後結果只能是 $p_1 p_2 \cdots p_k$,那麼如何才能得到 $p_1 p_2 \cdots p_k$?

找到 $\max(a_i)$,求得比小於它的最小 $2^x$,這樣一來先做一次乘法把 $n$ 乘到 ${p_1}^{2^x}{p_2}^{2^x} \cdots {p_k}^{2^x}$,然後做 $2^x$ 次開方操作即可得到 $p_1 p_2 \cdots p_k$。因此最少 $x+1$ 次操作。

(當然,還有一些數字本身就是最小結果,這些另作判斷即可。)

AC程式碼:

#include<bits/stdc++.h>
using namespace std;
int n;
pair<int,int> solve(int n)
{
    if(n<=1) return make_pair(n,0);
    int res=1,mx=0, mn=20;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            res*=i;
            int cnt=0;
            while(n%i==0) n/=i, cnt++;
            mx=max(cnt,mx);
            mn=min(cnt,mn);
        }
    }
    if(n>1) res*=n, mx=max(1,mx), mn=min(1,mn);
    int t=ceil(log2(mx))+1e-8;
    if(mn==mx && (1<<t)==mx) return make_pair(res,t);
    else return make_pair(res,t+1);
}
int main()
{
    while(cin>>n)
    {
        pair<int,int> ans=solve(n);
        cout<<ans.first<<' '<<ans.second<<endl;
    }
}

 


C - Banh-mi - []

 


D - Fun with Integers - []

 


E - Company - []