1. 程式人生 > >2018年第四階段組隊訓練賽第三場(BAPC2017 Preliminaries)

2018年第四階段組隊訓練賽第三場(BAPC2017 Preliminaries)

喜歡 friend ext mod 錯誤 exactly direct err 題目

D.Disastrous Doubling

題目描述

A scientist, E. Collie, is going to do some experiments with bacteria.Right now, she has one bacterium. She already knows that this species of bacteria doubles itself every hour. Hence, after one hour there will be 2 bacteria.
E. Collie will do one experiment every hour, for n consecutive hours.
She starts the ?rst experiment exactly one hour after the ?rst bacterium starts growing. In experiment i she will need bi bacteria.
How many bacteria will be left directly after starting the last experiment? If at any point there are not enough bacteria to do the experiment, print “error”.
Since the answer may be very large, please print it modulo 109+7.

輸入

The input consists of two lines.
? The ?rst line contains an integer 1 ≤ n ≤ 105
, the number of experiments.
? The second line contains n integers b1, . . . , bn, where 0 ≤ bi ≤ 260 is the number of bacteria used in the ith experiment.

輸出

Output a single line containing the number of bacteria that remains after doing all the experiments, or “error”.

樣例輸入

3
0 0 0

樣例輸出

8

題意:1個細菌一小時分裂一次,每次分裂後都會取走一部分細菌,問最後剩多少細菌(mod 1e9+7)

分析:

  wa了十幾發寫大數,java的Biginteger都用上了(我還沒學QAQ),還是一直超時。正解是:ans = (ans*2%mod-a[i]%mod+mod)%mod 但是這樣出來的一定是正數,無法判斷error的情況,所以要標記一個取的數的最大值,如果ans超過了這個值,那麽就不會出現負數了。在超過maxx之前,因為a[i]不會超過long long int,所以ans直接減就可以,然後判斷一下負數。

#include <bits/stdc++.h>

using
namespace std; const int mod = 1000000007; int main() { int n; scanf("%d",&n); long long int maxx = 0; long long int ans =1; long long int a[100005]; for(int i=0;i<n;i++) { scanf("%lld",&a[i]); if(a[i]>maxx) maxx = a[i]; } int flag = 0; maxx*=2; for(int i=0;i<n;i++) { if(flag) { ans = (ans*2%mod-a[i]%mod+mod)%mod; } else { ans*=2; if(ans>=maxx) flag = 1; ans-=a[i]; if(ans<0) { cout<<"error\n"<<endl; return 0; } } } printf("%lld\n",ans%mod); return 0; }

——————————————分割線———————————————————

E: Envious Exponents

Alice and Bob have an integer N. Alice and Bob are not happy with their integer. Last night they went to a cocktail party and found that another couple had the exact same integer! Because of that they are getting a new integer.

Bob wants to impress the other couple and therefore he thinks their new integer should be strictly larger than N.
Alice herself is actually fond of some speci?c integer k. Therefore, Alice thinks that whatever integer they pick, it should be possible to write it as a sum of k distinct powers of 2.

Bob is also a cheapskate, therefore he wants to spend as little money as possible. Since the cost of an integer is proportional to its size, he wants to get an integer that is as small as possible.

輸入

? A single line containing two integers N and k, with 1 ≤ N ≤ 1018 and 1 ≤ k ≤ 60.

輸出

Output M, the smallest integer larger than N that can be written as the sum of exactly k distinct powers of 2.

樣例輸入

1 2

樣例輸出

3

題意:給一個n和一個k 讓你求一個大於n的數,二進制有k個1,求這個數最小是多少。

分析:


代碼:(隊友的 話說我一直劃水) 情況有點多 我直接在代碼上加了註釋 希望能看懂

#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
int a[1000];
ll n;
ll k;
int main()
{
    scanf("%lld %lld",&n,&k);

    ll nn=n;
    int cnt=0;
    while(nn)  //用a[i]記錄n的二進制 cnt記錄多少位
    {
        a[cnt++]=nn%2;
        nn/=2;
    }
    int cnt1=0,flag=0,pos; //flag標記夠不夠k個1  flag==1說明夠 0不夠  //cnt1記錄二進制1的個數
    for(int i=cnt-1;i>=0;i--)
    {
        if(a[i]==1)
        {
            cnt1++;
            pos=i;
        }
        if(cnt1==k)
        {
            flag=1;
            a[i]=0;
            break;
        }
    }

    if(!flag) //1 is not enough
    {
            for(int i=0;i<cnt;i++) //倒著補0
            {
                if(a[i]==0)
                {
                    a[i]=1;
                    cnt1++;
                }
                if(cnt1==k)
                    break;
            }
            while(cnt1<k)  //補滿cnt位還不夠 繼續往前補
            {
                a[cnt++]=1;
                cnt1++;
            }

    }
    else //1 is enough
    {
        for(int i=0;i<pos;i++)
            a[i]=0;
        int flag1=0,pos1;
        for(int i=pos+1;i<cnt;i++) //pos記錄了第k個1的位置
        {
            if(a[i]==0)
            {
                a[i]=1;
                flag1=1;
                pos1=i;
                break;
            }
        }
        if(!flag1)  //n=1111000 k = 3  ->> 11100000
        {
            a[cnt++]=1;
            for(int i=cnt-2;i>=k-1;i--)
                a[i]=0;
            for(int i=0;i<k-1;i++)
                a[i]=1;
        }
        else        //n=(二進制)11011000 k=3的情況  ->>  11100000
        {
            int cnt2=0;
            for(int i=cnt-1;i>=pos1;i--)
                if(a[i]==1) cnt2++;
            for(int i=0;i<k-cnt2;i++)
                a[i]=1;
            for(int i=k-cnt2;i<pos1;i++)
                a[i]=0;
        }
    }
    ll ans=0;
    ll p=1;
    for(int i=0;i<cnt;i++)  
    {
        ans+=p*(ll)a[i];
        p*=2;
    }
    printf("%lld\n",ans);//自閉了啊啊啊啊啊啊啊啊啊啊啊啊
    return 0;
}

——————————————————————————分割線————————————————————-————————

H: Horror Film Night

題目描述

Emma and Marcos are two friends who love horror films. This year,and possibly the years hereafter, they want to watch as many films together as possible. Unfortunately, they do not exactly have the same taste in films. So, inevitably, every now and then either Emma or Marcos has to watch a film she or he dislikes. When neither of them likes a film, they will not watch it. To make things fair they thought of the following rule: They can not watch two films in a row which are disliked by the same person. In other words, if one of them does not like the current film, then they are reassured they will like the next one. They open the TV guide and mark their preferred films. They only receive one channel which shows one film per day. Luckily, the TV guide has already been determined for the next 1 million days.
Can you determine the maximal number of films they can watch in a fair way?

輸入

The input consists of two lines, one for each person. Each of these lines is of the following form:
? One integer 0 ≤ k ≤ 1000000 for the number of films this person likes;
? followed by k integers indicating all days (numbered by 0, . . . , 999999) with a film this person likes.

輸出

Output a single line containing a single integer, the maximal number of ?lms they can watch together in a fair way.

樣例輸入

1 40
2 37 42

樣例輸出

3

題意:
兩人去看電影 兩人有一些喜歡的電影 給你兩人喜歡電影放映的時間 兩人不能連著看一個人不喜歡的電影2場 問你最多能看多少場電影
分析:
貪心就行了
AC代碼:
比賽的時候,這份我寫的代碼沒有過,因為sort(a,a+n+m+1)少了個+1,之後隊友重寫了一遍過了
賽後找到錯誤 真的。。。。感覺自己沒有腦子
#include <bits/stdc++.h>
  
using namespace std;
const int maxn = 1e6+5;
struct node
{
    int num;
    int t;
} a[2*maxn];
//bool vis[maxn]={0};
  
int cmp(node a,node b)
{
    if(a.num==b.num)
        return a.t<b.t;
    return a.num<b.num;
}
  
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m;
    scanf("%d",&n);
  
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i].num);
        a[i].t = 0;
    }
    scanf("%d",&m);
    for(int i=n+1; i<=n+m; i++)
    {
        scanf("%d",&a[i].num);
        a[i].t = 1;
    }
    a[0].num = 0;
    a[0].t = -1;
    sort(a,a+n+m+1,cmp);
  
    int ans = 0;
//    if(n==0&&m==0)
//        ans = 0;
    for(int i=1; i<=n+m; i++)
    {
        if(a[i].t!=a[i-1].t)
        {
            ans++;
        }
        else
        {
            if(a[i+1].num==a[i].num)
            {
                ans++;
            }
        }
        if(a[i].num==a[i+1].num)
        {
            a[i+1].t = -1;
            i++;
        }
    }
    printf("%d\n",ans);
    return 0;
}



2018年第四階段組隊訓練賽第三場(BAPC2017 Preliminaries)