题目链接:点击打开链接
A: 给出n天的需求和肉的价格, 问你满足每天的需求需要花费的最少买肉价格是多少.
脑洞题目, 因为肉价格是已知的, 所以对每个上升的子序列需求求和, 乘以最低价格, 然后累加起来就是答案.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e5 + 5;
int n, a[MAXN], p[MAXN], ans, mi = 105;
int main(int argc, char const *argv[])
{
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d%d", &a[i], &p[i]);
ans += a[0] * p[0];
mi = p[0];
for(int i = 1; i < n; ++i)
if(p[i] >= mi) ans += a[i] * mi;
else {
mi = p[i];
ans += a[i] * mi;
}
printf("%d\n", ans);
return 0;
}
B: 给一个数字, 让你输出这个数的一个因子, 要求这个因子尽可能大且不可被任何数的平方所整除.
根据数据范围, 暴力做就可以. 由于要尽可能的大, 所以保存因子的时候用了优先队列, 最后判断即可.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
using namespace std;
const int MAXN = 1e6 + 10;
typedef long long ll;
ll n, p[MAXN], num;
priority_queue<ll> q;
void get_dis(ll x)
{
for(ll i = 1; i * i <= x; ++i)
if(x % i == 0) {
q.push(i);
q.push(x / i);
}
}
int main(int argc, char const *argv[])
{
scanf("%lld", &n);
for(ll i = 2; i * i <= n; ++i)
p[num++] = i * i;
get_dis(n);
while(!q.empty()) {
bool flag = false;
ll x = q.top();
for(int i = 0; i < num; ++i)
if(x % p[i] == 0) {
q.pop();
flag = true;
break;
}
if(!flag) {
printf("%lld\n", x);
return 0;
}
}
return 0;
}
C: 给出一个序列, 问你最少去除多少次可以使序列为空. 去除的条件是 2a1 + 2a2 + ... + 2ak = 2x
脑洞题目,. 记录序列中每个数的数目, 然后遍历一次, 每次操作使当前数除2加到后一个数, 如果为奇数那么ans就加1. 偶数则说明满足
条件.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e6 + 100;
int n, ans, a[MAXN];
int main(int argc, char const *argv[])
{
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
int x;
scanf("%d", &x);
a[x]++;
}
for(int i = 0; i < MAXN; ++i) {
a[i + 1] += a[i] >> 1;
ans += (a[i] & 1);
}
printf("%d\n", ans);
return 0;
}