2018年第四阶段组队训练赛第三场(BAPC2017 Preliminaries)

A: Abandoned Animal

参考:https://www.cnblogs.com/SoulSecret/p/9533123.html

题目描述
Your little sister has been a big help today: she went into town to do all the groceries! During this grand voyage, she was accompanied by her fluffy friend, Mr. Fluffynose the Stuffed Animal. However, after her return, it seems that she has left him somewhere along the route! This is devastating news for your little sister, and as she won’t stop crying about it, you decide to retrace her steps through town.

You know that your sister will hold on to her beloved Fluffynose whenever possible, so the only time she could’ve lost it is when she grabbed an item on her shopping list. So, all you have to do is figure out at what store she bought what, and then you’ll reunite her with her counterpart in no time! However, you soon find out that this isn’t quite as easy as you thought: she went to a lot of stores, and although she knows the names of the stores she went to and the order in which she visited them, she does not recall what she bought at each store (it could have been nothing!). It would take a lot of time to blindly search all the stores for all these items. As you have better things to do today, like solving programming problems, you want to spend as little time on this retrieval as possible. Therefore, you want to know exactly which items your sister bought at each store before you start your search. 

For this you have two pieces of information: firstly you know the inventory of all stores your sister went to.Secondly, you know exactly in what order she purchased the groceries, as she has very carefully stacked all items into her bag. You decide to number the stores your sister visited according to the order in which she visited them. Given this information, you want to decide whether you know for sure where she bought every item so you can retrace her steps as efficiently as possible.

 

输入
The input starts with a line with a single integer 1 ≤ N ≤ 100,000, the number of supermarkets in town. Then follows a line with an integer N ≤ K ≤ 100,000, after which K lines follow with a space-separated integer i (between 0 and N − 1) and a string S (consisting of only lowercase letters, at most 10), denoting that item S is available at the   ith store that your sister visited. It is guaranteed that every store has at least one item, every item is available
at at least one store, and that every item occurs at most once at every store.
The second part of the input contains the list of items your sister bought, in order of purchase.It starts with a line with an integer M ≤ K, the number of items your sister has bought. Then follow M lines, each with string T, denoting the name of the item your sister bought. The items are given in the order she purchased them in. All items that your sister has bought are unique.

 

输出
Output “impossible” if there is no path through the stores that matches your sister’s description.
Output “unique” if there is exactly one path through the stores that matches.
Output “ambiguous” if there are multiple possible paths.

 

样例输入
3
3
0 chocolate
1 icecream
2 cookies
3
chocolate
cookies
icecream

 

样例输出
impossible

题意:n,k n个商店0~n-1,共卖k个商品 接下来k行 每行给这个商品在哪个shop卖,
和商品的name(同一种商品可以在多个商店卖)。再给你一个m,是买的商品的数量,
接下来给你m个商品的name,有序。提问能否按照0~n-1商店的顺序,按顺序买到这m件物品,
不能输出”impossible“。方法一种,输出”unique“,多种输出”ambiguous“。
分析:
按照商店序号找m个商品
正着找一次 找不到impossible
反着找一次
找到且等于第一次 unique
不同 ambiguoous
代码:
#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e5+5;
typedef struct node
{
    int shopnum;
    string s;
};
int cmp(node a,node b)
{
    return a.shopnum<b.shopnum;
}
node mp[maxn];
int main()
{
    //freopen("in.txt","r",stdin);
    int n,k;
    cin>>n>>k;

    for(int i=0;i<k;i++)
    {
        cin>>mp[i].shopnum>>mp[i].s;
    }
    sort(mp,mp+k,cmp);

    int a[maxn],b[maxn];//a[]记录一个shop里商品第一个的位置 b[]记录最后一个的位置子

    for(int i=k-1;i>=0;i--)
    {
        a[mp[i].shopnum] = i;
    }
    for(int i=0;i<k;i++)
    {
        b[mp[i].shopnum] = i;
    }

    int m;
    cin>>m;

    int Left[maxn],Right[maxn],flag;  //两个数组用于判断是否唯一
    int now = 0; //标记当前商店第一个商品的位置
    string t[maxn];
    int flag1= 0;//判断impossible

    for(int i=0;i<m;i++) //正着找
    {
        cin>>t[i];
        if(flag1) continue;
        flag = 0;
        for(int j=now;j<k;j++)
        {
            if(t[i]==mp[j].s)
            {
                Left[i] = mp[j].shopnum;
                now = a[mp[j].shopnum];
                flag = 1;
                break;
            }
        }
        if(!flag)
        {
            flag1 = 1;
            break;
        }
    }
    if(flag1)
    {
        cout<<"impossible"<<endl;
        return 0;
    }
    now = k-1; //标记当前商店最后一个商品的位置
    for(int i=m-1;i>=0;i--)
    {
        for(int j=now;j>=0;j--)
        {
            if(t[i]==mp[j].s)
            {
                Right[i] = mp[j].shopnum;
                now = b[mp[j].shopnum];
                break;
            }
        }
        if(Right[i]!=Left[i])
        {
            cout<<"ambiguous"<<endl;
            return 0;
        }
    }
    cout<<"unique"<<endl;
    return 0;
}

 

——————————————————————————分割线————————————————————-————————

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 first experiment exactly one hour after the first 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 first 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 specific 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 films 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;
}

 



转载于:https://www.cnblogs.com/hao-tian/p/9533178.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值