A. Little Pony and Crystal Mine
水題,每行D的個數為1,3.......n-2,n,n-2,.....3,1,然後列印即可
#include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; int main(){ int n; cin >> n; vector<string> crystal(n,string(n,'*')); for(int i = 0 ; i <= n/2; ++ i){ int mid = n/2; for(int j = mid-i; j <= mid+i; ++ j) crystal[i][j]='D'; } for(int i = n-1 ; i > n/2; -- i){ int mid = n/2; for(int j = mid-(n-1-i); j <= mid+(n-1-i); ++ j) crystal[i][j]='D'; } for(int i = 0 ; i < n; ++ i ){ cout<<crystal[i]<<endl; } }
B. Little Pony and Sort by Shift
題目意思:
給一個序列a1,a2...an,每次操作將最後一個元素放在數列開始位置,即a1,a2.....an變成an,a1,a2......an-1,通過多少次操作可以將序列變成非遞減序列。
解題思路:
如果序列本身是非遞減序列,則輸出0
如果序列不是非遞減的,令pre=0, i=n-1,然後將a[i]與a[pre]比較,
如果a[i]≤a[pre],說明可以將a[i]放在數列前面,則更新pre=i,然後--i,繼續上面操作,直到a[i]>a[pre],則不能交換(如果交換後不能滿足非遞減序列),退出迴圈
再遍歷 0~i,是否滿足非遞減
#include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; int main(){ int n, res = 0; cin >>n; vector<int> a(n,0); bool flag = false; for(int i = 0 ; i < n; ++ i){ cin >> a[i]; if(i && a[i]<a[i-1]) flag = true; } if(flag){ int pre= 0, i = n-1; for( i = n-1; i >= 0; -- i){ if(a[i]<= a[pre]){ res++; pre = i; } else break; } for(int j = 0 ; j < i; ++ j){ if(a[j] > a[j+1]) {res=-1;break;} } } cout<<res<<endl; }
C. Little Pony and Expected Maximum
題目意思:
有一個m面的骰子,骰子投擲出數為1 ,2,3,4......m,每個數被投擲出的概率是1/m,然後將該骰子投擲n次,問投擲出大期望值是多少?(每次投擲都是相互獨立的)
解題思路:
現在以m=6,n=3為例說明投擲n次後,注意每種情況出現的概率是1/mn
最大值為1的情況是(1,1,1)
最大值為2的情況是三次投擲中至少有一次是2
當三次投擲中只有1次是2,則剩下2次,每次出現的情況只能是1,故有C(3,1)種可能
當三次投擲中只有2次是2,則剩下1次,只能出現1,故有C(3,2)種可能
當三次投擲全部是2時,則有C(3,3)種可能
故所有的可能數是C(3,1)+C(3,2)+C(3,3)
最大值為3的情況是三次投擲中至少有一次是3
當三次投擲中只有1次是3時,則剩下2次,每次出現的點數是1或者2兩種,故剩下2次的可能數是22 故整個可能數是C(3,1)*22 種可能
當三次投擲中只有2次是3時,則剩下1次,每次出現的點數是1或者2兩種,故剩下1次的可能數是21 故整個可能數是C(3,2)*21 種可能
當三次投擲中3次是3時,則剩下0次,每次出現的點數是1或者2兩種,故剩下2次的可能數是20 故整個可能數是C(3,3)*20 種可能
故所有的可能是C(3,1)*22 +C(3,2)*21 +C(3,3)*20
.................................
假設現在是m,n,最大值為k的情況是n次投擲中至少有一次是k
當n次投擲中只有1次是k時,則剩下n-1次,每次出現的點數是1....k-1任何一個數,故剩下n-1次的可能數是(k-1)n-1 故整個可能數是C(n,1)*(k-1)n-1種可能
當n次投擲中只有2次是k時,則剩下n-2次,每次出現的點數是1....k-1任何一個數,故剩下n-2次的可能數是(k-1)n-2 故整個可能數是C(n,2)*(k-1)n-2種可能
當n次投擲中只有3次是k時,則剩下n-3次,每次出現的點數是1....k-1任何一個數,故剩下n-1次的可能數是(k-1)n-3 故整個可能數是C(n,3)*(k-1)n-3種可能
....................................................
故所有的可能是C(n,1)*(k-1)n-1 +C(n,2)*(k-1)n-2+C(n,3)*(k-1)n-3+.............+C(n,n)*(k-1)n-n, 缺少C(n,0)*(k-1)n
根據公式(1+x)^n=C(n,n)+C(n,n-1)x^1+C(n,n-2)x^2+………+C(n,2)x^(n-2)+C(n,1)x^(n-1)+C(n,0)x^n
故上述所有可能等於(1+k-1)n-(k-1)n-1=kn-(k-1)n-1
故最大值為k的可能數是kn-(k-1)n-1
整個的期望是Σk(kn-(k-1)n-1)/mn,其中k=1......n
由於m,n都很大,用pow會溢位故需要處理,上述公式變為Σk(kn-(k-1)n-1)/mn=Σ(m(k/m)n+1-(k/k-1)(k-1/m)n)
#include <iostream> #include <cmath> #include <cstdio> using namespace std; int main(){ int m,n; cin >> m >> n; double res = 0; for(int i = 1; i <=m; ++i){ double a = double(i)/m, b = double(i-1)/m; res+=double(m)*pow(a,n+1)-double(i)*pow(b,n); } printf("%0.5f\n",res); }