< 已写:A 、B 、H 、 K>
更好的观看体验
其他的随后补
A - 小沙の好客
题目链接:小沙の好客
算法标签:【前缀和】【二分】
思路:先对商品的价格进行排序,然后进行前缀和操作,最后用二分函数upper_bound()找到第一个大于目标值的位置,遍历得出答案。
upper_bound()和lower_bound()的不同【@brandong】:
lower_bound(begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound(begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
代码:
代码链接
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll a[N] , s[N];
int n , q;
int k , x;
void solve()
{
scanf("%d%d",&k,&x);
/*二分找到目标值所在位置,减去数组初始位置,则为目标值下标*/
int r = upper_bound(a+1,a+n+1,x) - (a+1);
int l = max(0,r - k + 1);
/*利用前缀和,得出答案*/
printf("%lld\n",s[r] - s[l - 1]);
}
int main()
{
scanf("%d%d",&n,&q);
for(int i = 1;i <= n;i ++)
scanf("%lld",&a[i]);
sort( a+1 , a+1+n );
for(int i = 1;i <= n;i ++)
s[i] = s[i - 1] + a[i];
while( q-- )
solve();
return 0;
}
B - 小沙の博弈
题目链接:小沙の博弈
算法标签:【贪心】?(bushi)
思路:小沙和小雅两人分别取石子,小沙先取。每个人要使自己的字典序最小的话,每次只取一个,构成字典序:111...
。
- 如果石子的个数是偶数的话,每个人取到的石子数相同,平局。
- 如果石子的个数是奇数的话,小沙比小雅多取一个
(小沙先取!),因此小雅获胜。
代码:
代码链接
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if(n % 2 == 0)
puts("win-win!");
else
puts("Yaya-win!");
return 0;
}
H - 小沙の店铺
题目链接:小沙の店铺
算法标签:【模拟】
思路:每次售出时,可以用cnt
来记录共售卖的货品数,以便得到上涨后的价格。
- 注意开long long
代码:
代码链接
#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
ll x , y , k , n , t;
scanf("%lld %lld %lld %lld %lld",&x,&y,&k,&n,&t);
// x : 初始价格
// y : 每次上涨价格
// k : 卖出k个物品,涨价
// n : 共有n个客户
// t : gmv
ll pri = x; // 目前的价格
ll sum = 0; // 收入
ll cnt = 0; // 已售出的货物数量
ll i;
for(i = n;i >= 1;i --)
{
sum += pri*i; // 计算收入
cnt += i;
pri = x + (cnt/k) * y; // 计算涨价后的价格
if(sum >= t) // 如果达到目标值,直接退出
break;
}
if(sum < t) // 如果所有的顾客都已购买后,仍未达到目标值,输出-1
printf("-1\n");
else
printf("%lld\n",n-i+1);
return 0;
}
K - 小沙の抱团 easy
题目链接:小沙の店铺
算法标签:【模拟】【贪心】
思路:每次使得淘汰的人数最多,所需要的指令就越少
- 当场上的人数是偶数时,那么就抱团(人数/2+1),使得淘汰的人数最多
- 当场上的人数是奇数时,抱团(奇数/2)向上取整 --> (奇数+1)/2,使得淘汰的人数最多
代码:
代码链接
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
int main()
{
ll n;
scanf("%lld",&n);
ll ans = 0; // 存放指令个数
while(n > 2)
{
if( n%2 ) //奇数时
n = (n+1) / 2;
else // 偶数时
n = n / 2 + 1;
ans ++;
}
printf("%lld\n",ans);
return 0;
}