B
题意:
现有k种咖啡,编号0~k-1 ,每一种咖啡的价格为 2^k。现在你有 n 元,在每一种咖啡只买一杯或者不买的情况下,试问有多少种购买咖啡的组合(不买也算)
数学知识可以知道,n个数有2^n - 1个组合;如果他的钱可以买到第i个的话,那前面的组合都可以遍历到, 二进制 2^n 一定大于前n项和(eg: 2^5 > 2^4 + 2^3 + 2^2 + 2) 否则的话就是n + 1 种方案 ,如果他的钱比2^k(因为编号到k - 1)多,那就是2^k - 1个组合
k 位的二进制数可以表示 [ 0 , 2^k − 1 ] 之间的所有数。所以当 n ≤ 2^k − 1 时,区间 [ 0 , n ]内的数都可以被表示出来,所以答案为 n + 1。 每一个数都只有一种二进制表达方法,每个数都可以被表达出来2 = 0 + 2; 3 = 1 + 2; 4 = 0 + 4……(每种只能出现一次)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll t; cin >> t;
while(t --)
{
ll n, k;
cin >> n >> k;
if(k >= 32) cout << n + 1 << endl;
else
{
ll p = pow(2, k); //计算2^k
cout << min(n + 1, p) << endl;
}
}
return 0;
}
C
题目:
有n天假期,至少出去玩k天,每天(ai)温度不能超过q,超过了就不去,有几种出行方案
首先判断有多少天连续,如果连续的天数len大于k,则进行下一步
如果出行k天,则有(len-k+1)种出行方案,出行k + 1天,就有(len-k-1+1)种出行方案,出行k + 2天,有(len-k-1 -1+1)种,以此类推,出行len天,就有1种出行方案; 等差数列的求和公式是:(首项+尾项)* 项数 / 2 所以符合等差数列
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll t; cin >> t;
while(t --)
{
ll n, k, q, m = 0;
cin >> n >> k >> q;
vector<int>a(n + 1);
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i <= n; i ++)
{
if(a[i] <= q)
{
ll len = 0;
while(i <= n && a[i ++] <= q) len ++;
i --;//使其停留在符合条件的最后一个位子
if(len >= k)
m = m + (len - k + 1) * (len - k + 1 + 1) / 2;
}
}
cout << m << endl;
}
return 0;
}