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; }
原文地址:https://www.cnblogs.com/hao-tian/p/9533178.html