Tutorial CodeForces Round 289 (Div.2) (Second Winter Computer Camp Selection 2015) 題解

來源:互聯網
上載者:User

標籤:

題目連結:點擊開啟連結

A:

#include <cstdio>#include <vector>#include <algorithm>#include <iostream>#include <map>#include <set>#include <queue>#include <cstring>#include <cmath>#include <string>using namespace std;int a[12][11];int main() {    for (int i = 0; i <= 10; ++i) a[i][0] = a[0][i] = 1;    for (int i = 1; i <= 10; ++i) {        for (int j = 1; j <= 10; ++j) {            a[i][j] = a[i - 1][j] + a[i][j - 1];        }    }    int n;    scanf("%d", &n);    printf("%d\n", a[n - 1][n - 1]);    return 0;}
B:構造

#include <cstdio>#include <vector>#include <algorithm>#include <iostream>#include <map>#include <set>#include <queue>#include <cstring>#include <cmath>#include <string>using namespace std;typedef long long ll;const int N = 105;int n, m;int a[N];int main() {    while (~scanf("%d %d", &n, &m)){        int mi = 1000, mx = 0;        for (int i = 1; i <= n; i++){            scanf("%d", &a[i]);            mi = min(mi, a[i]);            mx = max(mx, a[i]);        }        if (mx - mi > m)puts("NO");        else {            puts("YES");            for (int i = 1; i <= n; i++){                for (int j = 1; j <= mi; j++)printf("%d ", 1);                a[i] -= mi;                for (int j = 1; j <= a[i]; j++)printf("%d ", j); puts("");            }        }    }    return 0;}
C:類比

題意:有一個n長的嚴格單調遞增序列,對於序列上某個點的權值就是數位和(即 123的數位和為6)

現在給出這個序列的數位和,構造一個序列使得最後一個數最小。

略麻煩,首先我們得到一個結論:對於給定的sum[i],我們目標是構造最小的且比前面的數大的數。

一定是構造最小的數,因為大的數我們也能用sum[i]構造,倒不如構造最小的。

構造時先判斷是否需要進位(即位元能不能和上一個數字一樣)

然後暴力遞增即可。

#include <cstdio>#include <vector>#include <algorithm>#include <iostream>#include <map>#include <set>#include <queue>#include <cstring>#include <cmath>#include <string>using namespace std;typedef long long ll;const int N = 305;int n;int Ni(vector<int>&x){//返回最低位且不為9的位置,若全為9返回-1    for (int i = 0; i < x.size(); i++)if (x[i] != 9)return i;    return -1;}void add(vector<int>&x){//讓x的數位和增加1    int ni = Ni(x);     if (ni == -1){//全為9時想要讓數位和增加1隻能在最高位添一個1        x.push_back(1);    }    else {        x[ni]++;    }}void hehe(vector<int>&now, vector<int>&old, int sum, int l){//當位元比上一個數字要大時,我們先構造一個100···這樣的序列,且使得這個序列位元最少且全為9時的數位和>=sum,然後暴力增加數位和即可    int dig = old.size() + 1;    while (dig * 9 < sum){        dig++;    }    dig--;    now.clear();    while (dig--)now.push_back(0); now.push_back(1);    sum--;    while (sum--)add(now);}void work(vector<int>&now, vector<int>&old, int sum,int l){    if (l < sum){//如果數位和已經比上一個數大就直接從上一個數開始增加數位和        now = old;        sum -= l;        while (sum--)add(now);        return;    }    else {        if (Ni(old) == -1 || old.size() * 9 < sum){            hehe(now, old, sum, l);            return;        }        now = old;        int s = 0;        int find = -1;        for (int i = now.size()-1; i >= 0; i--){//如果我們把上一個數的某一位 find 增加1,然後把個位到find位全變0,能使得數位和<=sum 那麼我們就不必增加位元,否則還是要增加位元            s += now[i];            if (now[i] < 9 && s + 1 <= sum){                find = i;            }        }        if (find!=-1){            now[find]++;            for (int i = 0; i < find; i++)now[i] = 0;            int ssum = sum;            for (int i = 0; i < now.size(); i++)ssum -= now[i];            if (ssum >= 0){                while (ssum--){ add(now); }                for (int i = now.size() - 1; i >= 0; i--)if (now[i]>old[i])                return;                else if (now[i] < old[i])break;            }        }        hehe(now, old, sum, l);         }}vector<int>u[2];int main() {    while (~scanf("%d", &n)){        u[0].clear(); u[1].clear();        u[1].push_back(0);        int cur = 0, last = 1;        int sum, l = 0;        while (n--){            scanf("%d", &sum);            work(u[cur], u[last], sum, l);            for (int i = u[cur].size() - 1; i >= 0; i--)putchar('0' + u[cur][i]);            puts("");            l = sum;            cur ^= 1; last ^= 1;        }    }    return 0;}/*5111116*/
D:

還不會,



E:

#include <cstdio>#include <vector>#include <algorithm>#include <iostream>#include <map>#include <set>#include <queue>#include <cstring>#include <cmath>#include <string>using namespace std;const int MAX_N = 500007;int bit[MAX_N << 1], len;int sum(int i) {    int s = 0;    while (i > 0) {        s += bit[i];        i -= i & -i;    }    return s;}void add(int i, int x) {    while (i <= len) {        bit[i] += x;        i += i & -i;    }}char str[MAX_N];bool is(char ch) {    return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' ||    ch == 'U' || ch == 'Y';}long long z[MAX_N];long long zz[MAX_N];int main() {    scanf("%s", str + 1);    len = strlen(str + 1);    for (int i = 1; str[i]; ++i) {        if (is(str[i])) z[i] = z[i - 1] + 1;        else z[i] = z[i - 1];    }    for (int i = 1; i <= len; ++i) {        zz[i] = zz[i - 1] + z[i];    }        double ans = 0;    for (int i = 0; i <= len; ++i) {        if (len - (i + 1) >= 0)             ans += (zz[len] - zz[len - (i + 1)] - (zz[i])) * 1. / (i + 1);        }    printf("%f\n", ans);    return 0;}


F:dp[l][r]表示 區間[l,r] 構成一棵樹的方法數。

對於一個區間[l, r] 構成一棵樹,則點l一定是根,然後枚舉2個區間相乘即可

dp[l][r] = dp[l+1][i] * dp[i+1][r] ( i = [l+1, r] )

當然 a[i+1] > a[l+1] ,這樣才會滿足題目中的暴力代碼。。==

import java.io.PrintWriter;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.Map;import java.util.PriorityQueue;import java.util.Scanner;import java.util.Stack;import java.util.TreeMap;import java.util.TreeSet;import java.util.Queue;public class Main {int n;int[] a = new int[N];long[][] dp = new long[N][N];long dfs(int l, int r){if(dp[l][r] != -1)return dp[l][r];if(l >= r)return dp[l][r] = 1;long ans = 0;for(int i = l+1; i <= r; i++)if(i == r || a[i + 1] > a[l + 1])ans = (dfs(l+1, i) * dfs(i, r)+ans)%mod;return dp[l][r] = ans;}void work() {while(cin.hasNext()){n = cin.nextInt(); for(int i = 1; i <= n; i++)a[i] = cin.nextInt();for(int i = 1; i <= n; i++){for(int j = i; j <= n; j++)dp[i][j] = -1;}System.out.println(dfs(1, n));}}Main() {cin = new Scanner(System.in);out = new PrintWriter(System.out);}public static void main(String[] args) {Main e = new Main();e.work();out.close(); }public Scanner cin;public static PrintWriter out;static int N = 505;DecimalFormat df=new DecimalFormat("0.0000");static int mod = 1000000007 ;}







Tutorial CodeForces Round 289 (Div.2) (Second Winter Computer Camp Selection 2015) 題解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.