Codeforces Round #259 (Div. 2)

OpenSoucre發表於2014-08-02

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;
    }
}
View Code

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;
}
View Code

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)*2種可能

    當三次投擲中只有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)*2+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);
}
View Code

 

相關文章