1. 程式人生 > 其它 >Educational Codeforces Round 118 (Div. 2)

Educational Codeforces Round 118 (Div. 2)

  • A. Long Comparison

題目大意:\(Monocarp\)在一個黑板上寫下了兩個數。每一個數都用兩個整數\(x,p\)表示,表示其值為\(x\)後有\(p\)\(0\)\(Monocarp\)想讓你比較這兩個數的大小。

思路:顯然直接模擬會炸···
將兩個數寫成科學計數法:\(a=x_1+10^{p_1}\),\(b=x_2+10^{p_2}\)
直接比不好比較,採用取對數比較即可:\(log_{10}a=log_{10}x_1+p_1\),\(log_{10}b=log_{10}x_2+p_2\),作差即可

Code:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long ll;
int t;
double x1,p1,x2,p2;
int main(){
    cin>>t;
    while(t--){
        cin>>x1>>p1>>x2>>p2;
        double ans;
        ans=log10(x1/x2)+p1-p2;
        if(ans==0) cout<<"="<<endl;
        else if(ans>0) cout<<">"<<endl;
        else cout<<"<"<<endl;
    }
    return 0;
}
  • B. Absent Remainder

題目大意:給你一個長度為\(n\)的序列,請找\(\left\lfloor\dfrac{n}{2}\right\rfloor\)個不同的二元組\((x,y)\)(兩個二元組不同滿足\(x\)不同或\(y\)不同),滿足以下性質:

  • \(x\ !=y\)
  • \(x\)\(y\)均在序列中
  • \(x\ mod\ y\)不在序列中

請輸出這些二元組。若有多種答案,輸出一種即可。

思路:由於\(x\ mod\ y<y\),因此我們選出序列中的最小值,那麼 \(x\ mod\ y\)肯定不會出現在序列中,\(y\)依次從\(max\)往前取,最多取\(n-1 >= \left\lfloor\dfrac{n}{2}\right\rfloor\)

,符合條件

Code:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long ll;
int t;
int n,a[N];
int main(){
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        sort(a+1,a+1+n);
        for(int i=1;i<=n/2;i++)cout<<a[n-i+1]<<" "<<a[1]<<endl;
    }
    return 0;
}
  • C. Poisoned Dagger

題目大意:\(Monocarp\)要斬殺一頭巨龍,巨龍的血量為\(h\)\(Monocarp\)可以發動\(n\)次攻擊,每次攻擊發動於時間\(a_i\),持續時間\(k\)秒,每持續\(1\)秒就會讓巨龍的血量\(-1\)。如果兩個攻擊的間隔小於\(k\),後一個攻擊發動時會停止前一個攻擊的效果。\(Monocarp\)想知道斬殺這頭巨龍的\(k\)的最小值是多少。

思路:根據題意可以得到對於每個\(a_i\)持續的區間為\([a_i,min(a_{i+1}-1,a_i+k-1)]\)(注意對於\(a_n\),顯然區間為\([a_n ,a_n+k]\))
\(n\)個區間求和得:$f(k)=\sum_{i=1}^{n-1}\bigl( min(a[i]+k-1,a[i+1]-1)-a[i]+1 \bigr)+k $
顯然該柿子關於\(k\)具有單調性,因此套二分答案即可求出最小的\(k\)

Code:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
ll n,h,a[N],t,ans;
ll check(ll mid){
	ll tt=0;
	for(int i=1;i<n;i++) tt+=min(a[i]+mid-1,a[i+1]-1)-a[i]+1;
	tt+=mid;
	return tt;
}
int main(){
	cin>>t;
	while(t--){
		cin>>n>>h; 
		for(int i=1;i<=n;i++) cin>>a[i];
		ll l=0,r=h+1;
		while(l<=r){
			ll mid=(l+r)>>1;
			if(check(mid)>=h){
				ans=mid;
				r=mid-1;
			}
			else l=mid+1;
		}
		cout<<ans<<endl;
	}
	return 0;
}