2016CCPC長春 - B/D/F/H/I/J/K - (待補)

目錄:

B - Fractionphp

D - Trianglec++

F - Harmonic Value Description數組

H - Sequence Ipromise

I - Sequence IIapp

 


B題:HDU 5912 - Fraction - [遞歸]

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=5912ide

Problem Description
Mr. Frog recently studied how to add two fractions up, and he came up with an evil idea to trouble you by asking you to calculate the result of the formula below:this

As a talent, can you figure out the answer correctly?
idea

Input
The first line contains only one integer T, which indicates the number of test cases.spa

For each test case, the first line contains only one integer n (n≤8).code

The second line contains n integers: $a_1,a_2,⋯a_n(1\le a_i \le 10)$.
The third line contains n integers: $b_1,b_2,⋯,b_n(1 \le b_i \le 10)$.

Output
For each case, print a line 「Case #x: p q」, where x is the case number (starting from 1) and p/q indicates the answer.

You should promise that p/q is irreducible.

Sample Input
1
2
1 1
2 3

Sample Output
Case #1: 1 2

Hint

Here are the details for the first sample:
2/(1+3/1) = 1/2

 

題意:

給出了關於 $a[1:n]$ 和 $b[1:n]$ 的計算式,給你 $a[1:n]$ 和 $b[1:n]$,要求計算式結果。

 

題解:

因爲範圍很小,直接遞歸計算便可。

 

AC代碼:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn=10;

int n;
int a[maxn],b[maxn];

inline int gcd(int m,int n){return n?gcd(n,m%n):m;}
pii dfs(int dist)
{
    if(dist==n)
    {
        int u=b[n];
        int d=a[n];
        int g=gcd(u,d);
        return make_pair(u/g,d/g);
    }

    pii f=dfs(dist+1);
    int u=b[dist]*f.second;
    int d=a[dist]*f.second+f.first;
    int g=gcd(u,d);
    return make_pair(u/g,d/g);
}
int main()
{
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++) cin>>b[i];
        pii ans=dfs(1);
        printf("Case #%d: %d %d\n",kase,ans.first,ans.second);
    }
}

 


D題:HDU 5914 - Triangle - [貪心]

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=5914

Mr. Frog has n sticks, whose lengths are 1,2,3,⋯,n respectively.  is a bad man, so he does not want Mr. Frog to form a triangle with three of the sticks here. He decides to steal some sticks! Output the minimal number of sticks he should steal so that Mr. Frog cannot form a triangle with any three of the remaining sticks.

Input

The first line contains only one integer T (T≤20), which indicates the number of test cases. For each test case, there is only one line describing the given integer n (1≤n≤20).

Output

For each test case, output one line 「Case #x: y」, where x is the case number (starting from 1), y is the minimal number of sticks Wallice should steal.

Sample Input

3
4
5
6

Sample Output

Case #1: 1
Case #2: 1
Case #3: 2

 

題意:

有 $n$ 根棍子,長度分別爲 $1,2,3,\cdots,n$,如今要從中取出若干棍子使得剩下的棍子任意三條均不能組成一個三角形,求最少取出多少根棍子。

 

題解:

首先考慮最開始的 $1,2,3$ 三根木棍都是能夠留下來的,而長度爲 $4$ 的則須要拿走,由於 $2+3>4$,而後 $5$ 又能夠留下, 由於正好 $2+3=5$,依次類推,不難發現就是一個斐波那契數列。

 

AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=25;

int n;
int fibo[maxn];
int main()
{
    int T;
    cin>>T;
    fibo[1]=1;
    fibo[2]=2;
    for(int i=3;i<maxn;i++) fibo[i]=fibo[i-1]+fibo[i-2];
    for(int kase=1;kase<=T;kase++)
    {
        cin>>n;
        printf("Case #%d: %d\n",kase,n-(upper_bound(fibo+1,fibo+maxn,n)-(fibo+1)));
    }
}

 


F題:HDU 5916 - Harmonic Value Description - [思惟題]

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=5916

The harmonic value of the permutation $p_1,p_2,⋯,p_n$ is

$\sum\limits_{i = 1}^{n - 1} {\left( {p_i p_{i + 1} } \right)}$

Mr. Frog is wondering about the permutation whose harmonic value is the strictly k-th smallest among all the permutations of [n].

Input

The first line contains only one integer T (1≤T≤100), which indicates the number of test cases.

For each test case, there is only one line describing the given integers n and k (1≤2k≤n≤10000).

Output

For each test case, output one line 「Case #x: $p_1$ $p_2$ ⋯ $p_n$」, where x is the case number (starting from 1) and $p_1$ $p_2$ ⋯ $p_n$ is the answer.

Sample Input

2

4 1

4 2

Sample Output

Case #1: 4 1 3 2

Case #2: 2 4 1 3

 

題意:

給出 $[1:n]$ 的一個排列 $p_1$ $p_2$ ⋯ $p_n$,認爲其調和值爲 $\sum\limits_{i = 1}^{n - 1} {\left( {p_i p_{i + 1} } \right)}$,

如今對於 $[1:n]$ 的全部排列,要求其調和值爲第 $k$ 小的排列是哪個。

 

題解:

首先 $1,2,3,4,5,6\cdots,n$ 這樣的排列,很明顯「調和值」最小,爲 $n-1$,

若咱們把 $2$ 移動至 $3,4$ 之間的位置,就會變成:$1,3,2,4,5,6,\cdots ,n$,不難發現,調和值爲 $n$,由於從 $4$ 日後的全部數字都沒有變化,gcd值仍是 $1$,惟一變化的是 $2,4$ 的gcd值爲 $2$,也就是原來多了 $1$,

能夠大膽假設:第 $k$ 小調和值的排列,就是把 $1,2,3,4,5,6\cdots,n$ 中的 $k$ 取出來,放到 $2k-1,2k$ 之間。

不妨檢驗一下 $k=3$,咱們先將 $3$ 移至 $5,6$ 之間獲得:$1,2,4,5,3,6,7,8,\cdots,n$,發現 $gcd(3,6) = 3$,確實比原來增長了2,

可是,存在問題, 本來 $2,4$ 由 $3$ 隔開,如今併到了一塊兒,gcd值也增長了,那麼咱們不妨把 $1$ 拿過來填掉這個原來是 $3$ 的坑,獲得:$2,1,4,5,3,6,7,8,\cdots,n$,調和值爲 $n+1$,就是第 $3$ 小的,完美。

因此,對於任意的 $k$ 知足 $2k \le n$,只要將 $k$ 移動至 $2k$ 以前,將 $1$ 移動至原來 $k$ 的位置,就能獲得調和值第 $k$ 小的排列。

(不由自主就像$%$一下個人神仙隊友,這都能想獲得,tql(`・ω・´)>)

 

AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=25;

int n,k;
int main()
{
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        cin>>n>>k;
        printf("Case #%d: ",kase);
        if(k==1) for(int i=1;i<=n;i++) printf("%d%c",i,(i==n)?'\n':' ');
        else
        {
            for(int i=2;i<=k-1;i++) printf("%d ",i);
            printf("1 ");
            for(int i=k+1;i<=2*k-1;i++) printf("%d ",i);
            printf("%d ",k);
            for(int i=2*k;i<=n;i++) printf("%d%c",i,(i==n)?'\n':' ');
        }
    }
}

 


H題:HDU 5918 - Sequence I - [KMP]

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=5918

Mr. Frog has two sequences $a_1,a_2,⋯,a_n$ and $b_1,b_2,⋯,b_m$ and a number $p$. He wants to know the number of positions $q$ such that sequence $b_1,b_2,⋯,b_m$ is exactly the sequence $a_q,a_{q+p},a_{q+2p},⋯,a_{q+(m−1)p}$ where $q+(m−1)p \le n$ and $q \ge 1$.

Input

The first line contains only one integer $T \le 100$, which indicates the number of test cases.Each test case contains three lines.

The first line contains three space-separated integers $1 \le n \le 10^6,1 \le m \le 10^6$ and $1 \le p \le 10^6$.

The second line contains $n$ integers $a_1,a_2,⋯,a_n(1 \le a_i \le 10^9)$. The third line contains $m$ integers $b_1,b_2,⋯,b_m(1 \le b_i \le 10^9)$.

Output

For each test case, output one line 「Case #x: y」, where x is the case number (starting from 1) and y is the number of valid q’s.

Sample Input

2

6 3 1

1 2 3 1 2 3

1 2 3

6 3 2

1 3 2 2 3 1

1 2 3

Sample Output

Case #1: 2

Case #2: 1

 

題意:

給出一個長度爲 $n$ 的文本串,一個長度爲 $m$ 的模式串,給出跳步長度 $p$,

要求在文本串中,若按照跳步長度 $p$ 來進行遍歷,求能找獲得多少個模式串。

 

題解:

特喵的這個就是個KMP模板題,一開始看完題目就想着枚舉開頭,把全部的跳步長度爲 $p$ 的子序列處理出來了,

可是那個時候不知道發什麼神經,竟然算不清處理出來的若干個子序列的總長是多少!!!覺得是 $O(n^2)$ 的總長度就沒敢寫,後來一看榜單怎麼過的人這麼多,確定就是個水題啊!

而後仔細一看,就反應過來了,這若干個子序列的總長就是 $O(n)$ 啊!

假設文本串的編號是 $0$ 到 $n-1$ 的,那麼咱們只須要開一個表頭大小爲 $p$ 的鄰接表來存這若干個子序列(表頭就是 $0,1,2,\cdots,p-1$),對於編號爲 $i$ 那個字符,扔進表頭爲 $i%p$ 的那個鏈表裏去就好了呀!!!每一個字符確定只會出現一次,因此這若干個子序列的總長就是 $O(n)$……

而後就好辦了,對鄰接表裏的每一個鏈表,就當成一個文本串,拿去和模式串KMP匹配一下,求得當前子序列中出現了幾回模式串,最後求和一下就是答案了;

總的時間複雜度 $O(n+m)$。

 

AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;

int n,m,p;
vector<int> str[maxn];
int pat[maxn];

int Next[maxn];
void getNext()
{
    int i=0, j=-1, len=m;
    Next[0]=-1;
    while(i<len)
    {
        if(j == -1 || pat[i] == pat[j]) Next[++i]=++j;
        else j=Next[j];
    }
}
int kmp(int p)
{
    int i=0, j=0, len1=str[p].size(), len2=m;
    if(len1<len2) return 0;
    int ans=0;
    while(i<len1)
    {
        if(j == -1 || str[p][i] == pat[j]) i++, j++;
        else j=Next[j];
        if(j == len2) ans++;
    }
    return ans;
}

int main()
{
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++)
    {
        scanf("%d%d%d",&n,&m,&p);

        for(int i=0;i<p;i++) str[i].clear();
        for(int i=0,a;i<n;i++)
        {
            scanf("%d",&a);
            str[i%p].push_back(a);
        }

        for(int i=0;i<m;i++) scanf("%d",&pat[i]); pat[m]=0;
        getNext();

        int ans=0;
        for(int i=0;i<p;i++) ans+=kmp(i);
        printf("Case #%d: %d\n",kase,ans);
    }
}

注意:

這裏有一個WA點,首先KMP的模板是沒錯的,可是KMP的模板對應的是char數組的字符串,而咱們這裏是數字序列;

咱們都知道,字符串讀入時,位置 $0 \sim n-1$ 存實際字符串,位置 $n$ 存一個 '\0',KMP的模板裏是有使用到這個性質的;

而當咱們for循環讀入數字時,是沒有這個 '\0' 終止符的,因此咱們應當相似於字符串讀入的方式,在位置 $n$ 存一個 $0$(將全部序列可能出現的數字做爲一個集合,取該集合範圍以外的數字)做爲終止符。

 


I題: HDU 5919 - Sequence II - [主席樹]

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=5919

Mr. Frog has an integer sequence of length n, which can be denoted as $a_1,a_2,⋯,a_n$.

There are m queries. In the i-th query, you are given two integers $l_i$ and $r_i$. Consider the subsequence $a_{l_i},a_{l_{i+1}},a_{l_{i+2}},⋯,a_{r_i}$.

We can denote the positions (the positions according to the original sequence) where an integer appears first in this subsequence as $p_1^{(i)},p_2^{(i)},⋯,p_{k_i}^{(i)}$ (in ascending order, i.e., $p_1^{(i)} < p_2^{(i)} < ⋯ < p_{k_i}^{(i)}$).

Note that $k_i$ is the number of different integers in this subsequence. You should output $p_{\left\lceil {\frac{{k_i }}{2}} \right\rceil }^{(i)}$ for the i-th query.

Input

In the first line of input, there is an integer T (T≤2) denoting the number of test cases.

Each test case starts with two integers n (n≤2e5) and m (m≤2e5).

There are n integers in the next line, which indicate the integers in the sequence(i.e., $a_1,a_2,⋯,a_n$, $0 \le a_i \le 2e5$).

There are two integers $l_i$ and $r_i$ in the following $m$ lines.

However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to $l'_i,r'_i$($1 \le l'_i \le n, 1 \le r'_i \le n$).

As a result, the problem became more exciting. We can denote the answers as $ans_1,ans_2,⋯,ans_m$.

Note that for each test case $ans_0=0$.

You can get the correct input $l_i,r_i$ from what you read (we denote them as $l'_i,r'_i$) by the following formula: $l_i = min{(l'_i+ans_{i−1}) mod n + 1,(r'_i + ans_{i−1}) mod n+1}, r_i = max{(l'_i + ans_{i−1}) mod n + 1, (r'_i+ans_{i−1}) mod n + 1}$

Output

You should output one single line for each test case. For each test case, output one line 「Case #x: $ans_1,ans_2,⋯,ans_m$」, where x is the case number (starting from 1) and $ans_1,ans_2,⋯,ans_m$ is the answer.

 

題意:

給出 $n(n \le 2e5)$ 個數,每一個數的大小知足 $0 < a_i \le 2e5$,

給出 $m(m \le 2e5)$ 個詢問,對於每一個詢問輸入 $l,r$,序列 $a_l,...,a_r$ 中的每一個數,在該序列內第一次出現的位置,合成一個序列 $P$;

若假設這個區間有 $k$ 個不一樣的數,咱們獲得的序列 $P$ 就是 $p_1 < p_2 < p_3 < ... <p_k$;

而對應於該查詢的答案爲:序列中 $P$ 的第 $\left\lceil {\frac{k}{2}} \right\rceil = \left\lfloor {\frac{{k + 1}}{2}} \right\rfloor$ 個數。

例如:

整個序列爲:$1,5,2,2,5,1,4,5,1$;

查詢區間爲 $[1,5]$,即 $1,5,2,2,5$,對應產生的序列 $P$ 即爲 $1,2,3$,長度 $k=3$,答案爲 $p_{\left\lfloor {\frac{{3 + 1}}{2}} \right\rfloor } = p_2 = 2$;

查詢區間爲 $[2,7]$,即 $5,2,2,5,1,4$,對應產生的序列 $P$ 即爲 $2,3,6,7$,長度 $k=4$,答案爲 $p_{\left\lfloor {\frac{{4 + 1}}{2}} \right\rfloor } = p_2 = 3$;

查詢區間爲 $[6,9]$,即 $1,4,5,1$,對應產生的序列 $P$ 即爲 $6,7,8$,長度 $k=3$,答案爲 $p_{\left\lfloor {\frac{{3 + 1}}{2}} \right\rfloor } = p_2 = 7$;

(固然,查詢的輸入那裏加了一點小操做,不影響總體大意,第 $i$ 個查詢的區間要經過 第 $i-1$ 個查詢的答案計算獲得)。

 

題解:

相關文章
相關標籤/搜索