日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2020 乐山师范学院新生程序设计大赛题解

發布時間:2024/1/8 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020 乐山师范学院新生程序设计大赛题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2020 樂山師范學院新生程序設計大賽題解

A 數組求和

中等難度

題目大意:

給定一個數組,執行若干次操作,每次操作可以把兩個相鄰的數變成相反數,求數組最大的和。

解題思路:

這其實是一個思維題,認真思考會發現,最大和,肯定希望數組中的負數是最小的,最好全都是非負數。基于這個思想,會發現,經過若干次操作后,可以讓負數的位置自由移動。例如 n = 5 , ? 5 , 4 , 3 , 2 , 1 n = 5, {-5, 4, 3, 2, 1} n=5?5,4,3,2,1,第一次移動選擇下標 1,結果就會變成 5 , ? 4 , 3 , 2 , 1 {5, -4, 3, 2, 1} 5,?4,3,2,1,會發現,負數的位置向移動了一,不難發現,在經過 3 3 3 次操作后,數組就會變為 5 , 4 , 3 , 2 , ? 1 {5, 4, 3, 2, -1} 5,4,3,2,?1,此時,數組和就是最大的。

所以這題的做法就很明顯了:

統計負數的個數:

  • 如果是偶數個,就可以全部轉換成正整數,因為可以任意移動,就移動成倆倆一對,最后再翻轉過來,所以全都會變成正數。

  • 如果是奇數,那必然只會有一個負數,就讓絕對值最小的數變成負數即可。

最后求和判斷下即可:

代碼:

#include <iostream> #include <math.h> using namespace std;const int maxn = 1e5 + 5;int main() {int n;int sum = 0; // 最后的答案和int mi = 10000; // 記錄絕對值最小的int cnt = 0; // 負數的個數cin >> n;for(int i = 0; i < n; ++i) {int a; cin >> a;sum += abs(a); // 直接加上絕對值if(abs(a) < mi)mi = abs(a);if(a < 0)++cnt;}if(cnt % 2 == 1) sum -= 2 * mi; // 如果是奇數個,因為之前加了一個,所以要減去兩倍cout << sum << endl;return 0; }

B 超級短的題

困難?反正我是感覺挺困難的。

題目大意:

給定一個數字 n n n,求 n ! n! n! 的最右邊有多少個連續的 0 0 0

解題思路:

這有點數學題的味道,要先想清楚數字最右邊的 0 0 0 是怎么來,其實就是 10 10 10 的倍數, 100 100 100 的倍數,以此類推。也就是說一個數有幾個因子是 10 10 10,最右邊就有幾個 0 0 0。所以這題就轉換成怎么求 10 10 10 這個因子的個數。

10 10 10 分解下質因子就是 2 2 2 5 5 5 ,也就是找 n ! n! n! 因子里有幾個 2 2 2 5 5 5,然后取最小值即可。

這就是一個數學公式:

f ( n ) = ∑ i = 1 ∞ n p i f(n) = \displaystyle\sum_{i=1}^{\infty}\cfrac{n}{p^i} f(n)=i=1?pin?

其實是求 p p p 的倍數有幾個, p 2 p^2 p2 的倍數有幾個 . . . ... ... 最后累加就是答案

照著這個公式寫代碼即可

其實只用求因子 5 5 5 的個數,因為 5 5 5 的個數是遠遠小于 2 2 2 的個數.

代碼:

#include <iostream> #include <math.h> using namespace std;const int maxn = 1e5 + 5;int main() {int n;cin >> n;int ans = 0;for(int i = 5; i <= n; i *= 5)ans += n / i;cout << ans << endl;return 0; }

題目短,代碼也短 _

C 時光倒流

簽到題

題目大意:

給一個 BO5 的比分,看誰能贏。

解題思路:

一個 if 就搞定了

代碼:

#include <iostream> #include <math.h> using namespace std;const int maxn = 1e5 + 5;int main() {int n, m;cin >> n >> m;if(n == 3) cout << "DWG win!\n";else cout << "SN win!\n";return 0; }

D 這好像是一道簽到題?

困難。楊會自己出的一道題,和 B 題其實是一樣的,代碼很短,思路有點難

題目大意:

最小化操作次數,使得數組符合題目公式的要求
f ( l , r ) = ∑ i = l r a i ? ∑ i = l r i f(l,r)=\sum^{r}_{i=l}{a_i}-\sum^{r}_{i=l}{i} f(l,r)=i=lr?ai??i=lr?i
任意的 f ( l , r ) f(l, r) f(l,r) 都是 r ? l + 1 r-l+1 r?l+1 的倍數

解題思路:

這是一個構造體。因為要求數組和最小, 所以 $f(l, r) = r - l +1 $ , 這一步一定要理解,只要這樣,才是倍數關系,并且是最小的。再觀察這個上面的公式,結合剛才結論,當所有的 a i = i + 1 a_i = i+1 ai?=i+1 時,就是符合條件的,因為一一對應相減,貢獻就是 1,有幾個數就有幾個1,就會剛好滿足條件。

所以最終構造的數組其實就是 [ 2 , 3 , 4 , . . . , n , n + 1 ] [2, 3, 4, ..., n, n+1] [2,3,4,...,n,n+1],那最后的問題其實就是最少要多少次,才能把原來的數組構建成目標數組。

這涉及到貪心策略,大致思路就是直接把當前數字減到目標數字,或者減到前一個數字,次數取小累加即可。為什么可以這樣,首先最多就是直接減到目標數字,這是肯定可以的,或者減到和前面一樣,這樣前面減的時候可以一起減,所以后面的就不用算。兩個取最小的即可。

代碼:

#include <iostream> #include <algorithm> using namespace std;const int maxn = 1e6 + 5;long long a[maxn];int main() {int n;long long sum = 0;cin >> n;a[0] = 1;for(int i = 1; i <= n; ++i) {cin >> a[i];// min 和 max 都是 C++ 的函數,傳遞兩個參數,返回最小或者最大值,使用的話要導入頭文件algorithmsum += min(a[i]-i-1, max(0LL, a[i]-a[i-1]));}cout << sum << endl;return 0; }

E 追女孩

簽到-簡單難度 (這個方法可以嘗試下_

題目大意:

給出你和女孩的坐標以及各自的速度,問你能不能追上女生,被追不算

一個坑點就是 當兩人的位置相等時,也是算追上的。

解題思路:

又是一個 if 即可搞定,

代碼:

#include <iostream> using namespace std;int main() {int x, y;int n, m;cin >> x >> y;cin >> n >> m;if(x == y || (x < y && n > m))cout << "Yes\n";elsecout << "No\n";return 0; }

F 我怎么會不知道學校的域名?

中等+難度

題目大意:

在給定字符串中,找到符合 l s n u a c m lsnuacm lsnuacm

解題思路:

一般來講,設計到字符串的題目,難度都會高一點,其實實現起來并不難,就是根據題目的規則模擬匹配即可,可以看代碼。

代碼:

#include <iostream> #include <string.h> using namespace std;const int maxn = 1e6 + 5;char s[maxn]; char t[] = "lsnuacm";int main() {cin >> s;int n = strlen(s); // 字符串s的長度int m = strlen(t); // 題目要求 t 的長度// 標志變量, 0表示已經匹配了0個,1表示已經匹配了1個,以此類推int flag = 0;// 答案int cnt = 0;for(int i = 0; i < n; ++i) {// 找 s[i] 是在 t 中的第幾個int j;for(j = 0; j < m; ++j)if(t[j] == s[i])break;// 如果是開頭就是把flag設置為1if(j == 0) flag = 1;else if(j >= m) continue; // 如果不是t中的字符,根據題目規則,需要跳過else if(j == flag) // 如果剛好找的是下一個,匹配數就加一++flag;else flag = 0; // 否則就重置為0if(flag == m) { // 如果已經匹配了m個字符,就表明已經出現了一個,答案加一,并把標志位清空flag = 0;++cnt;}}cout << cnt << endl;return 0; }

G 我愛畫沙漏

簡單+難度

題目大意:

我覺的大家都能看懂

解題思路:

非常經典的一個畫圖題,一般分兩次畫,一次畫倒三角,一次畫正三角

代碼:

#include <iostream> using namespace std;int main() {int n;cin >> n;int d = n / 2;// 倒三角for(int i = 0; i <= d; ++i) {for(int j = 0; j < i; ++j)cout << " ";for(int j = 0; j < n-i*2; ++j)cout << "*";cout << endl;}// 正三角for(int i = 1; i <= d; ++i) {for(int j = 0; j < d-i; ++j)cout << " ";for(int j = 0; j < i*2+1; ++j)cout << "*";cout << endl;}return 0; }

H 找出所有的重復數字

中等+難度

題目大意:

找出數組中重復的數字,如果沒有或者有負數輸出 ? 1 -1 ?1

解題思路:

這題需要一個技巧,計數技巧,即用數組來統計數字出現的次數。具體看代碼

代碼:

#include <iostream> using namespace std;const int maxn = 1e6 + 5; int cnt[maxn]; int a[maxn];int main() {int n;int flag = 1;cin >> n;for(int i = 0; i < n; ++i) {cin >> a[i];if(a[i] < 0) flag = 0;else ++cnt[a[i]]; // 用數字做下標}if(!flag) { // 出現負數的情況cout << -1 << endl;return 0;}flag = 0;for(int i = 0; i < n; ++i) {if(cnt[i] > 1) {flag = 1; // 說明有重復的數字cout << i << " ";}}if(flag) cout << endl;else cout << -1 << endl;return 0; }

I 小學二年級的數學問題

中等難度

題目大意:

就是分數字, 兩邊的個數要一樣,要求差值最小,也就是盡可能均分

解題思路:

這是 2 的冪次形式,所以有 2 1 + 2 2 + 2 3 + . . . + 2 n ? 1 < 2 n 2^1+2^2+2^3+...+2^{n-1} < 2^n 21+22+23+...+2n?12n

其實很容易想到,選一個最大的,剩下的全選最小的,差值就是最小的

代碼:

#include <iostream> using namespace std;int main() {int n;cin >> n;int ans = 1 << n; // 左移一位就是乘2,移n位就是乘n個2int i;for(i = 1; i < n/2; ++i)ans += 1 << i;for(; i < n; ++i)ans -= 1 << i;cout << ans << endl;return 0; }

J 她生氣了

簡單難度 (get新知識_,蔡隊就是這樣哄女朋友的)

題目大意:

你女朋友現在生氣,說一個詞女朋友的生氣值就會少些,要說多少個詞

解題思路:

就是做一個除法就可以了,余下的也要在說一個

代碼:

#include <iostream> using namespace std;int main() {int n, m;cin >> n >> m;int ans = n / m;if(n % m) ++ans;cout << ans << endl;return 0; }

總結

以上是生活随笔為你收集整理的2020 乐山师范学院新生程序设计大赛题解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。