2020 年百度之星·程式設計大賽 - 初賽二
阿新 • • 發佈:2020-07-25
Poker
Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 98Accepted Submission(s): 39
傳送門
初始他有n塊錢,每一輪他需要投入至少m塊錢,系統會拿走其中p%的錢,並把剩下的錢還給他。
請問在最優情況下,小沃沃最多可以玩多少輪?
假設當前一輪小沃沃投入了x塊錢,那麼他可以收回⌊x×(1−p%)⌋塊錢,其中⌊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 解題思路:簽到題,每次至少投入m快錢,每次系統拿掉p%也就是說每次會減少m*p%的錢,用一個迴圈,每次模擬,當剩下的錢不夠m的時候退出就行 AC程式碼:
#include<cstdio> intmain(void) { int t,n,m,p; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&p); int sum=0; while(n>=m)//判斷條件 { n-=(m*p/100.0);//每次減少的錢 sum++; } printf("%d\n",sum); } return 0; }
Distance
Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)傳送門
Problem Description 小沃沃所在的世界是一個二維平面。他有n個朋友,第i個朋友距離他的距離為a[i],小沃沃並不知道這些朋友具體在什麼點上。
請問在最優情況下,小沃沃的朋友兩兩之間的歐幾里得距離的和的最小值是幾?
假設小沃沃的位置為P0=(x0,y0),第i個朋友的位置為Pi=(xi,yi),對於所有的i,需要滿足dist(P0,Pi)=a[i],並且∑n−1i=1∑nj=i+1dist(Pi,Pj)最小,其中dist(X,Y)為連線點X和點Y的線段的長度。xi,yi都可以是任意實數。
Input 第一行一個正整數test(1≤test≤10)表示資料組數。
對於每組資料,第一行一個正整數n(1≤n≤100000)。
接下來一行n個整數,第i個整數a[i](1≤a[i]≤1000000000)表示第i個朋友和小沃沃的距離。
Output 對每組資料輸出一行一個數,表示∑n−1i=1∑nj=i+1dist(Pi,Pj)的最小值。答案需要四捨五入到整數。
Sample Input 2 2 3 5 5 1 2 3 4 5
Sample Output 2 20
解題思路:不要被題目的表面迷惑了,什麼xi,yi對題目沒有任何影響,我們只知道小沃沃的朋友距離小沃沃的長度,什麼時候他的朋友們的相互距離之和最小呢,我們都知道直線有最短距離
那麼他的朋友就是站成一條直線的。我們會想到用一個兩層迴圈去做,有些人就存在僥倖心理,莽一發O(n^2)直接交上去,然後秒T,沒錯就是我,,。
T掉之後,我們就會想優化,其實很容易發現當朋友們連成一條直線的時候,對朋友們的距離進行排序,就能得到有序的陣列,然後我們發現在計算的時候會有重複的部分,然後我們減去重複的部分就好了啊。
設K為第一個到其他的總和,那麼k0=10,然後每次減去(n-i)*b[i],不斷讓k更新。
AC程式碼:
#include<cstdio> #include<algorithm> using namespace std; #define maxn 100005 #define ll long long bool cmp(ll a,ll b) { return a<b; } ll a[maxn],b[maxn]; int main(void) { ll t,n; scanf("%lld",&t); while(t--) { scanf("%lld",&n); ll sum=0; for(ll i=0;i<n;++i) { scanf("%lld",&a[i]); } sort(a,a+n,cmp); ll k=0;//這個k表示的是第一個朋友到其他朋友的距離總和 for(ll i=1;i<n;++i) { b[i]=a[i]-a[i-1];//求相鄰朋友的距離 k+=(n-i)*b[i]; } for(ll i=1;i<n;++i) { sum+=k;//每次加上每個朋友到其他朋友的距離(未被新增距離的朋友) k-=(n-i)*b[i];//更新k的值 } printf("%lld\n",sum); } }