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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2020年百度之星程序设计大赛-初赛二(Poker、Distance)

發布時間:2023/12/9 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020年百度之星程序设计大赛-初赛二(Poker、Distance) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2020年百度之星程序設計大賽-初賽二前兩題(Poker、Distance)解答代碼思路
Poker

Problem Description
小沃沃在玩一個有趣的游戲。
初始他有 n 塊錢,每一輪他需要投入至少 m 塊錢,系統會拿走其中 p% 的錢,并把剩下的錢還給他。
請問在最優情況下,小沃沃最多可以玩多少輪?
假設當前一輪小沃沃投入了 x 塊錢,那么他可以收回 ?x×(1?p%)? 塊錢,其中?a? 表示 a 取下整。 小沃沃每一輪投入的錢不能超過他現在擁有的錢。
每一輪投入的錢必須為整數。

Input
第一行一個正整數 test(1≤test≤100000) 表示數據組數。
對于每組數據,一行三個整數 n,m,p(1≤n≤100000,1≤m≤1000,1≤p≤100)。
Output
對每組數據輸出一行一個整數表示答案。

Sample Input 2 10 2 50 10 2 100 Sample Output 9 5

這道題比較簡單,第一次提交遇到超時問題,后來使用了scanf和printf解決問題。

Accept代碼:

#include<bits/stdc++.h> using namespace std; int main() {int test,n,m,sum;float p;cin>>test;while(test--){scanf("%d%d%f",&n,&m,&p);//cin和cout會超時 int r=n,nums=0;while(r>=m){ nums++;r=r-m*p*0.01;}printf("%d\n",nums); }return 0; }

目前官方提示: 觀察到小沃沃每次只會投入 m 塊錢,當他手上的錢大于等于 m 時,他可以繼續玩,每次會被拿走?m?p%? 這么多錢。那么就很好算了。

Distance

Problem Description
小沃沃所在的世界是一個二維平面。他有 nn 個朋友,第 ii 個朋友距離他的距離為 a[i],小沃沃并不知道這些朋友具體在什么點上。
請問在最優情況下,小沃沃的朋友兩兩之間的歐幾里得距離的和的最小值是幾?
假設小沃沃的位置為 P_0 = (x_0,y_0),第 i 個朋友的位置為 P_i = (x_i,y_i),對于所有的 i,需要滿足 dist(P_0, P_i) = a[i],并且∑ i=1 n?1∑ j=i+1 n dist(Pi,Pj) 最小,其中 dist(X,Y)dist(X,Y) 為連接點 XX 和點 YY 的線段的長度。x_i,y_i都可以是任意實數。

Input
第一行一個正整數 test(1≤test≤10) 表示數據組數。
對于每組數據,第一行一個正整數 n(1≤n≤100000)。
接下來一行 n 個整數,第 i 個整數 a[i] (1≤a[i]≤1000000000) 表示第 i 個朋友和小沃沃的距離。
Output
對每組數據輸出一行一個數,表示∑ i=1 n?1∑ j=i+1 ndist(Pi,P j) 的最小值。答案需要四舍五入到整數。

Sample Input 2 2 3 5 5 1 2 3 4 5 Sample Output 2 20

這道題目也好理解,寫程序思路直接,只是又遇到了超時問題。

#include<bits/stdc++.h> #include<cstdlib> using namespace std; //int a[1000000005];//數組太大,會出錯 int *a = new int[1000000005];//全局變量動態分配 int main() {int test,n,i,j;scanf("%d",&test);while(test--){ scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a[i]);int sum=0;sort(a+1,a+n+1);//排序i=1;while(i<=n-1) // for(i=1;i<=n-1;i++)//時間復雜度O(n^2),超時{j=i+1;for(j=i+1;j<=n;j++){sum=sum+a[j]-a[i];}i++;}printf("%d\n",sum);}delete a;return 0; }

這道題目出現超時問題,可能數組很大或者算法不夠好,兩個for循環時間復雜度較高O(n^2),雖然本地測試的時間限時小于1000ms,但是提交還是超時了,后續需要看看其他大佬怎么做的……

目前官方提示:最優情況下,所有人必然在由小沃沃出發的在一條射線上(任意兩個人的距離都最小)。我們把 a 排序以后,算距離和就比較簡單了。

測試時間:


我來更新啦,這個解法就Accept了,轉化思路,可以通過數學推導就計算最小的距離,最終時間復雜度為O(n)。
Accept代碼:

#include<bits/stdc++.h> typedef long long LL; using namespace std;int main() {int test,n,i,j;ios::sync_with_stdio(false);//避免超時cin.tie(0);cout.tie(0);cin>>test;while(test--){cin>>n;vector<LL> a(n);for(i=0;i<n;i++)cin>>a[i];LL sum=0;sort(a.begin(),a.end());for(i=0;i<n-1;i++){//可通過數學推導得出,實現O(n)的時間復雜度 sum += (a[i+1] - a[i]) * (LL)(i + 1) * (LL)(n - i - 1);}cout<<sum<<'\n';}return 0; }

sum += (a[i+1] - a[i]) * (i + 1) * (n - i - 1)
關鍵的這一步數學推導可能有許多朋友存在疑問,為什么能用此取而代之2個for循環呢?
我的推導思路是這樣的:
根據題目我們假設更普遍的數據為a[4]={3,5,8,11},我們容易發現在2次循環做法時候,是存在許多重復計算的。
比如:計算3與8的距離,我們用到了3與5、5與8的距離,即是a[2]-a[0]=8-3=2+3, a[1]-a[0]=5-3=2。以此類推。

dist(3,8)dist(3,5)dist(5,8)
a[2]-a[0]=8-3=2+3a[1]-a[0]=5-3=2a[2]-a[1]=8-5=3

我們似乎發現了規律,這種做法類似于動態規劃,避免了重疊子問題的計算導致效率降低,所以針對這道題可以采用只計算每一個子問題一次,再記錄每個子問題被計算的次數,進而提高效率,降低時間復雜度。

(a[i+1] - a[i]) * (i + 1) * (n - i - 1)
分析:
1、a[i+1] - a[i] 就是相鄰2個元素的距離,這個好理解。
2、i+1 就是 a[i+1] 元素之前需要用到a[i+1] - a[i]距離計算的次數。
3、n -i -1 就是 a[i] 元素之后需要用到a[i+1] - a[i]距離計算的次數。
舉例
a[4]={3,5,8,11}
根據推導式子為:
第一輪:2 * 1 * 3 = 6
第二輪:3 * 2 * 2 = 12
第三輪:3 * 3 * 1 = 9
計算結果27,與我們自行計算一致。實現O(N)時間復雜度。

我的博客園:https://www.cnblogs.com/chenzhenhong/p/13377665.html
我的CSND博客:https://blog.csdn.net/Charzous/article/details/107581452

總結

以上是生活随笔為你收集整理的2020年百度之星程序设计大赛-初赛二(Poker、Distance)的全部內容,希望文章能夠幫你解決所遇到的問題。

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