2020第十一屆藍橋杯7月省賽I題

2021-10-24 17:17:27 字數 1941 閱讀 3113

題目描述:

本題思路:

這道題,暴力過30%的樣例,拿的了7分的樣子,要全過的話那得dp,寫數學式子分析,找到盡可能減少複雜度的方法。

先上暴力**(這道題暴力寫應該很容易的):

#include

using

namespace std;

const

int n =

1e5+10;

typedef

long

long ll;

int n, k;

int a[n]

;int

main()

for(

int i =

0; i < n -

1; i++

)int lenx =

log10

(x)+1;

int leny =

log10

(y)+1;

ll nowx = y *

pow(

10, lenx)

+ x;

ll nowy = x *

pow(

10, leny)

+ y;if(

!(nowx % k))if

(!(nowy % k))}

} cout << cnt << endl;

return0;

}

數學分析:

判斷兩個數的拼接是否能被k整除,假設當前運算元為a[i], a[j]。

拼接之後的數就是a[i]*10^(log10a[j]) + a[j],對k取模,式子就是(a[i]*10 ^ (log10a[j] + 1) % k + a[j] % k)% k,這個式子的範圍在0~10 ^ 5之間,我們對這個式子進行分解分析:

第一部分:a[ i ] * 10 ^ (log10a[j] + 1) % k,其實就可以算出a[i]乘以不同的冪對k取模值為前面那個式子的個數,即用dp[冪][a[i]*10^(log10a[j]) % k]記錄個數

第二部分:a[j] % k,就可以根據上面得到的個數直接找到k - a[j] % k有多少個,這兩項之和可以被k整除,因為a[j] % k 可能為0,所以就再取一次模,(k - a[j] % k)% k.

然後在遍歷的時候直接累加到ans裡面就行

**部分solve()函式解決的就是記錄個數的部分,但是因為是在計數部分進行ans的更新的,所以ans記錄的只有當前某個運算元a[i]之前拼接的個數。

所以我們還得反向進行一次計算,即直接把陣列a翻轉一下,mst一下cnt,再跑一遍solve()即可。

最後輸出ans就可以啦~

**部分:

#include

#define mst(a, n) memset(a, n, sizeof(a))

using

namespace std;

typedef

long

long ll;

const

int n =

1e5+10;

int a[n]

;int cnt[11]

[n];

//cnt[i][j]表示i次冪下模k後值為j的個數

int n, k;

ll ans;

void

solve()

}}intmain()

solve()

;//拼接a[j][i]

mst(cnt,0)

;reverse

(a, a + n)

;solve()

;//拼接a[i]a[j]

cout << ans << endl;

return0;

}

2020第十一屆藍橋杯7月省賽J題

題目描述 本題思路 這道題是乙個帶權並查集,當初一看到這個題目的時候應該就要想到並查集,因為有權值的存在,所以我們可以想到帶權並查集。我們如果普通維護當前結點與父結點之間的關係的話,很明顯非常難維護,但是如果我們維護當前結點與祖先結點之間的關係的話,那就會好很多,我們每次把更新操作都在祖先結點上面做...

第十一屆藍橋杯

問題描述 小藍要為一條街的住戶製作門牌號。這條街一共有 2020 位住戶,門牌號從 1 到 2020 編號。小藍製作門牌的方法是先製作 0 到 9 這幾個數字字元,最後根據需要將字 符貼上到門牌上,例如門牌 1017 需要依次貼上字元 1 0 1 7,即需要 1 個 字元 0,2 個字元 1,1 個...

第十一屆藍橋杯省賽 走方格

時間限制 1.0s 記憶體限制 512.0mb 本題總分 20 分 問題描述 在平面上有一些二維的點陣。這些點的編號就像二維陣列的編號一樣,從上到下依次為第 1 至第 n 行,從左到右依次為第 1 至第 m 列,每乙個點可以用行號和列號來表示。現在有個人站在第 1 行第 1 列,要走到第 n 行第 ...