1. 程式人生 > 其它 >百度之星-初賽二

百度之星-初賽二

a搬磚之餘看到了幾個月前報名的百度之星初賽的簡訊通知,emmm,那就參加試試吧。就搞定了前兩題,記錄一下吧

第一題.簽到

思路:

通過下面的k依次變大,我們可以得到下面兩個公式

a b k
a b 0
a+b a-b 1
2a 2b 2
2(a+b) 2(a-b) 3
4a 4b 4
4(a+b) 4(a-b) 5
.... .... ....
2(k/2)*(a+b) 2(k/2)*(a-b) k%2==1
2(k/2)*a 2(k/2)*b k%2==0

但是這裡的k很大,並且結果還要取模,所以我們這裡應該用快速冪去求。

但是在這裡我沒有注意到負數取模

的問題,所以一直不知道哪裡錯,最後看了題目下面的提問才知道。對於(a-b)可能出現負數,比如(-3)%10,程式算的會是-3,而正確的應該是(-3)%10+10 = 7,程式碼裡我們讓它再加上一下我們取的模就可以了。

程式碼:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 998244353;

ll Pow(ll a, ll b)
{
    ll sum = 1;
    while (b) {
        if (b & 1) {
            sum = (sum * a) % mod;
            b--;
        }
        b /= 2;
        a = a * a % mod;
    }
    return sum;
}

int main()
{
    int t;
    cin >> t;
    while(t--){
        ll a,b,k;
        ll a1,b1;
        cin >> a >> b >> k;
        if(k%2==1){
            a1 = (((a+b)%mod)*Pow(2,k/2))%mod;
            b1 = (((a-b+mod)%mod)*Pow(2,k/2))%mod;
        }
        else{
            a1 = (Pow(2,k/2)*a)%mod;
            b1 = (Pow(2,k/2)*b)%mod;
        }
        cout << a1 << " " << b1 << endl;
    }
    return 0;
}

第二題.隨機題意

思路

這是一道貪心的題目,主要思想是對a陣列排序一下,對於每個a[i], b[i]滿足我們貪心要求的取值範圍是 [a[i]-k,a[i]+k] ,我們每次取我們能取到的最小的那個數,通過設定一個min_x來記錄上次b[i]取的數,我們就在當前範圍取一個最小且比min_x大的數,如果取不到就繼續下面的b[i],統計能取到的數的個數,就是答案。

程式碼

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn];
int main()
{
    int t;
    cin >> t;
    while(t--){
        int n,k;
        cin >> n >> k;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);//cin >> a[i];
        sort(a,a+n);
        int cnt = 0;
        int min_x = a[0]-k-1;
        for(int i=0;i<n;i++){
            int Max = a[i]+k;
            int Min = a[i]-k;
            if(Min<=min_x && min_x<Max){
                cnt++;
                min_x++;
            }
            else if(Min>min_x){
                cnt++;
                min_x = Min;
            }
        }
        cout << cnt << endl;
    }
    return 0;
}

溜了溜了,繼續搬磚去了