2017中國大學生程序設計競賽-總決賽-重現賽(感謝哈工大)


昨天的CCPC杭州怎么說好的還是取消了,那么今天就來玩玩這個總決賽

Dogs and Cages

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0
Special Judge


Problem Description
Jerry likes dogs. He has  N dogs numbered 0,1,...,N1. He also has N cages numbered 0,1,...,N1. Everyday he takes all his dogs out and walks them outside. When he is back home, as dogs can’t recognize the numbers, each dog just randomly selects a cage and enters it. Each cage can hold only one dog.
One day, Jerry noticed that some dogs were in the cage with the same number of themselves while others were not. Jerry would like to know what’s the expected number of dogs that are NOT in the cage with the same number of themselves.
 

 

Input
The first line of the input gives the number of test cases,  TT test cases follow.
Each test case contains only one number N, indicating the number of dogs and cages.
1T105
1N105
 

 

Output
For each test case, output one line containing “Case #x: y”, where  x is the test case number (starting from 1) and y is the expected number of dogs that are NOT in the cage with the same number of itself.
y will be considered correct if it is within an absolute or relative error of 106 of the correct answer.
 

 

Sample Input
2
1
2
 

 

Sample Output
Case #1: 0.0000000000
Case #2: 1.0000000000
Hint
In the first test case, the only dog will enter the only cage. So the answer is 0. In the second test case, if the first dog enters the cage of the same number, both dogs are in the cage of the same number, the number of mismatch is 0. If both dogs are not in the cage with the same number of itself, the number of mismatch is 2. So the expected number is (0+2)/2=1.
 
A題火速簽到啊,隨機生成n的全排列,a[i]!=i的數學期望
1只能正確,2可以在1個正確和1個錯誤的情況下加上1,遞歸可以發現是n*(n-1),那么數學期望就是n-1
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        printf("Case #%d: %d\n",++ca,n-1);
    }
    return 0;
}
Evil Forest
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 241    Accepted Submission(s): 119


Problem Description
The Bear, king of the forest, loves painting very much. His masterpiece – “Back in time” is very famous around all over the forest. Recently he wants to hold a series painting competition to select those animals who are good at painting as well. So the Bear appoints his minister Tiger to help him prepare the painting competitions.
Tiger owns a stationery factory which produces sketchpad, so he wants to let all the competitions use the sketchpads produced by his factory privately. The Bear plans to hold  N painting competitions, and informs Tiger of the number of competitors who are ready for each competition. One competitor needs only one sktechpad in one competition. For each competition, at least 10% extra sketchpads are required as backup just in case.
The Tiger assigns you, his loyal subordinate to calculate the minimum number of sketchpads produced
by his factory.
 

Input
The first line of the input gives the number of test cases,  TT test cases follow.
For each test case, the first line contains an integer N, where N is the number of competitions. The next line contains N integers a1,a2,...,aN representing the number of competitors in each competition.
1T100
1N1000
1ai100
 

Output
For each test case, output one line containing “Case #x: y”, where  x is the test case number (starting from 1) and y is the minimum number of sketchpads that should be produced by Tiger’s factory.
 

Sample Input
1
6
13 11 11 11 13 11
 

Sample Output
Case #1: 82
Hint
For the first test case, two more sketchpads should be prepared for each painting competition.
 

 
這個才是真正的簽到題,可是自己沒有看出來就是求下一個數的110%x的和,這個時候要向上取整
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        int s=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            s+=x+x/10+(x%10!=0);
        }
        printf("Case #%d: %d\n",++ca,s);
    }
    return 0;
}

Rich Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
One day, God Sheep would like to play badminton but he can’t find an opponent. So he request Mr. Panda to play with him. He said: “Each time I win one point, I’ll pay you  X dollars. For each time I lose one point, you should give me Y dollars back.”
God Sheep is going to play K sets of badminton games. For each set, anyone who wins at least 11 points and leads by at least 2 points will win this set. In other words, normally anyone who wins 11 points first will win the set. In case of deuce (E.g. 10 points to 10 points), it’s necessary to lead by 2 points to win the set.
Mr. Panda is really good at badminton so he could make each point win or lose at his will. But he has no money at the beginning. He need to earn money by losing points and using the money to win points.
Mr. Panda cannot owe God Sheep money as god never borrowed money. What’s the maximal number of sets can Mr. Panda win if he plays cleverly?
 

 

Input
The first line of the input gives the number of test cases,  TT test cases follow.
Each test case contains 3 numbers in one line, XY , K, the number of dollars earned by losing a point, the number of dollars paid by winning a point, the number of sets God Sheep is going to play.
1T105.
1X,Y,K1000.
 

 

Output
For each test case, output one line containing “Case #x: y”, where  x is the test case number (starting from 1) and y is the maximal number of sets Mr. Panda could win.
 

 

Sample Input
2
10 10 1
10 10 2
 

 

Sample Output
Case #1: 0 Case #2: 1
Hint
In the first test case, Mr. Panda don’t have enough money to win the only set, so he must lose the only set. In the second test case, Mr. Panda can lose the first set by 0:11 and he can earn 110 dollars. Then winning the second set by 11:0 and spend 110 dollars.
 

 

這個題目我感覺還是挺毒的啊,要把全部情況分析出來
賺的比輸得多,那就多打幾場全贏了,否則要按照11:9去贏,0:11去輸,這樣可以少輸點錢,直接解不等式就可以了,很簡單的。我好想本來是考慮錯了,然后因為x y弄反了多wa了幾次,太傻了
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    while(T--)
    {
        int x,y,k,s;
        scanf("%d%d%d",&x,&y,&k);
        if(x>y)
            s=k;
        else
            s=11*k*x/(11*y+2*x);
        printf("Case #%d: %d\n",++ca,s);
    }
    return 0;
}

Knightmare

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
A knight jumps around an infinite chessboard. The chessboard is an unexplored territory. In the spirit of explorers, whoever stands on a square for the first time claims the ownership of this square. The knight initially owns the square he stands, and jumps  N times before he gets bored.
Recall that a knight can jump in 8 directions. Each direction consists of two squares forward and then one squaure sidways.

After N jumps, how many squares can possibly be claimed as territory of the knight? As N can be really large, this becomes a nightmare to the knight who is not very good at math. Can you help to answer this question?
 

 

Input
The first line of the input gives the number of test cases,  TT test cases follow.
Each test case contains only one number N, indicating how many times the knight jumps.
1T105
0N109
 

 

Output
For each test case, output one line containing “Case #x: y”, where  x is the test case number (starting from 1) and y is the number of squares that can possibly be claimed by the knight.
 

 

Sample Input
3
0
1
7
 

 

Sample Output
Case #1:1
Case #2: 9
Case #3: 649
 

 

一看就是找規律的題,
然后想想矩陣快速冪不對啊,因為沒有MOD
所以肯定直接找規律就行了,寫代碼打表得到了前10項的值,第11項因為棧的問題已經爆炸掉了
1,9,41,109,205,325,473,649,853,1085,1345
然后前后相減沒什么規律,繼續相減最后幾個都是28啊,最后的增量和28有關,前幾項試特殊項,找到了那個增量是28*n-20,寫一下化簡一下,試了試都對
但是我還是沒估算好答案,爆了一發ll,要ull
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    int a[5]={1,9,41,109,205};
    while(T--)
    {
        unsigned long long n;
        scanf("%llu",&n);
        printf("Case #%d: ",++ca);
        if(n<5)
            printf("%d\n",a[n]);
        else
            printf("%llu\n",(n*14-6)*n+5);
    }
    return 0;
}

Alice’s Stamps

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
Alice likes to collect stamps. She is now at the post office buying some new stamps.
There are  N different kinds of stamps that exist in the world; they are numbered 1 through N. However, stamps are not sold individually; they must be purchased in sets. There are M different stamp sets available; the ith set contains the stamps numbered Li through Ri. The same stamp might appear in more than one set, and it is possible that one or more stamps are not available in any of the sets.
All of the sets cost the same amount; because Alice has a limited budget, she can buy at most K different sets. What is the maximum number of different kinds of stamps that Alice can get?
 

 

Input
The input starts with one line containing one integer  T, the number of test cases.T test cases follow.
Each test case begins with a line containing three integers: NM, and K: the number of different kinds of stamps available, the number of stamp sets available, and the maximum number of stamp sets that Alice can buy.
M lines follow; the ithoftheselinesrepresentsthei^{th} stamp set and contains two integers, Li and Ri, which represent the inclusive range of the numbers of the stamps available in that set.
1T100
1KM
1N,M2000
1LiRiN
 

 

Output
For each test case, output one line containing “Case #x: y”, where  x is the test case number (starting from 1) and y is the maximum number of different kinds of stamp that Alice could get.
 

 

Sample Input
2 5 3 2 3 4 1 1 1 3 100 2 1 1 50 90 100
 

 

Sample Output
Case #1: 4 Case #2: 50
Hint
In sample case #1, Alice could buy the first and the third stamp sets, which contain the first four kinds of stamp. Note that she gets two copies of stamp 3, but only the number of different kinds of stamps matters, not the number of stamps of each kind. In sample case #2, Alice could buy the first stamp set, which contains 50 different kinds of stamps.
 

有一點沒搞對,都沒來得及交,就是一個簡單的dp

以下為后來改的代碼
#include<bits/stdc++.h>
using namespace std;
int dp[2005][2005];
int l[2005];
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    while(T--)
    {
        memset(l,0,sizeof l);
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0; i<m; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            for(int i=x; i<=y; i++)
                l[i]=max(l[i],y);
        }
        memset(dp,0,sizeof dp);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<k; j++)
            {
                if(l[i+1])dp[l[i+1]][j+1]=max(dp[i][j]+l[i+1]-i,dp[l[i+1]][j+1]);
                dp[i+1][j]=max(dp[i][j],dp[i+1][j]);
            }
        }
        int ans=0;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=k; j++)
                ans=max(ans,dp[i][j]);
        printf("Case #%d: %d\n",++ca,ans);
    }
    return 0;
}

 

這個端點維護有很大問題,只是先把不覆蓋的轉移了,解決掉了端點的重合問題
#include<bits/stdc++.h>
using namespace std;
int dp[2005][2005];
int l[2005],f[2005];
int main()
{
    int T,ca=0;
    scanf("%d",&T);
    while(T--)
    {
        memset(l,0,sizeof l);
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0; i<m; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            l[x]=max(l[x],y);
        }
        int ans=0;
        memset(dp,0,sizeof dp);
        memset(f,0,sizeof f);
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<k; j++)
            {
                if(l[i])
                {
                    dp[i][j]+=(f[i]==0);
                    dp[l[i]][j+1]=dp[i][j]+l[i]-i;
                    f[l[i]]=1;
                }
                dp[i+1][j]=max(dp[i][j],dp[i+1][j]);
            }
            ans=max(ans,dp[i][k]);
        }
        printf("Case #%d: %d\n",++ca,ans);
    }
    return 0;
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM