先看下题目吧
题目1 : hohahola
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
有一种叫作hohahola的饮料,售价是X元一瓶。小Hi非常喜欢这种饮料,但是他现在身无分文。
不过小Hi有N张优惠券,买hohahola时每瓶最多使用一张优惠券,可以使该瓶价格减少Y元。(Y ≤ X)
同时优惠券可以出售,小Hi每出售一张优惠券可以获得Z元。
请你帮小Hi计算通过出售若干优惠券,他最多可以买多少瓶hohahola。
输入
一行4个整数N, X, Y, Z。
1 ≤ N, Z ≤ 1000000000 1 ≤ Y ≤ X ≤ 1000000000
输出
一个整数表示答案
样例输入
100 3 2 1
样例输出
50
这题我直接把函数写出来了,求个极值就好,不过要注意z-y有可能小于0或大于0.不过看了大佬的代码,他们好像是二分,我直接就把答案写出来了。
#include<bits/stdc++.h>
using namespace std;
long long n,x,y,z;
int main()
{
cin >> n >> x >> y >> z;
long long ans;
double t = 1.0 * z / (x - y) + 1;
double temp2 = n / t;
long long temp1 = z * temp2 / (x - y);
ans = temp1;
if(z - y >= 0)
ans = z * n / x;
cout << ans;
}
1745 : 最大顺子
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
你有N张卡片,每张卡片上写着一个正整数Ai,并且N张卡片上的整数各不相同。
此外,你还有M张百搭卡片,可以当作写着任意正整数的卡片。
一个“顺子”包含K张卡片,并且满足卡片上的整数恰好是连续的K个正整数。我们将其中最大的整数称作顺子的值。
例如1-2-3-4-5的值是5,101-102-103的值是103。
请你计算用给定的N张卡片和M张百搭卡片,能凑出的值最大的顺子是多少,并且输出该顺子的值。
输入
第一行包含3个整数,N,M和K。
第二行包含N个整数,A1, A2, … AN。
对于50%的数据,1 ≤ N, K ≤ 1000
对于100%的数据,1 ≤ N, K ≤ 100000 0 ≤ M < K
输出
一个整数代表答案
样例输入
10 1 5
1 4 2 8 5 7 10 11 13 3
样例输出
11
这题也不难,县排序,倒着查找,arr[i]与arr[i] + k之间需要填充的数小于m是就行了。
#include<bits/stdc++.h>
using namespace std;
int n,m,k,arr[100001],d[100001] = {0};
vector<int> v;
int main()
{
cin >> n >> m >> k;
for(int i = 1;i <= n;++i)
cin >> arr[i];
sort(arr + 1,arr + n + 1);
int ans = 0,i = n;
for(int j = n;i > 0;--i)
{
while(arr[i] + k - 1 < arr[j])
--j;
if(j - i + 1 >= k - m)
break;
}
ans = arr[i] + k - 1;
cout << ans;
}
1746 : 路径包含问题
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一棵N的节点的树,节点编号1~N,并且1号节点是根节点。
小Hi会反复询问小Ho一个问题:给定两个节点a和b,有多少对节点c和d满足c < d且c到d的路径包含完整的a到b的路径?
你能帮帮小Ho吗?
输入
第一行包含两个数N和M,依次是节点总数和问题总数。
第2~N行每行包含两个整数u和v,代表u是v的父节点。
以下M行每行包含两个整数a和b,代表一个问题。
对于30%的数据,1 ≤ N, M ≤ 1000
对于100%的数据,1 ≤ N, M ≤ 100000
输出
对于每个问题输出一个整数,代表答案。
样例输入
7 2
1 2
1 3
2 4
2 5
3 6
3 7
2 3
2 4
样例输出
9
6
这题就是lca问题,用倍增法解决
#include<bits/stdc++.h>
using namespace std;
int n,m,depth[100001],ancestor[21][100001]= {0};
long long sum[100001] = {0};
vector<int> child[100001];
int dfs(int num,int d)
{
sum[num] = 1;
for(int i = 0;i < (signed)child[num].size();++i)
{
depth[child[num][i]] = d + 1;
sum[num] += dfs(child[num][i],d + 1);
}
return sum[num];
}
int main()
{
cin >> n >> m;
for(int i = 2;i <= n;++i)
{
int temp1,temp2;
cin >> temp1 >> temp2;
child[temp1].push_back(temp2);
ancestor[0][temp2] = temp1;
}
depth[1] = 1;
dfs(1,1);
for(int i = 1;i <= 20;++i)
for(int j = 1;j <= n;++j)
ancestor[i][j] = ancestor[i - 1][ancestor[i - 1][j]];
while(m)
{
int temp1,temp2;
cin >> temp1 >> temp2;
if(depth[temp1] < depth[temp2])
swap(temp2,temp1);
int j = 20,t = temp1;
while(j >= 0 && depth[temp2] + 1 <= depth[temp1])
{
//cout << j;
if(ancestor[j][temp1] && depth[ancestor[j][temp1]] > depth[temp2])
temp1 = ancestor[j][temp1];
--j;
}
long long ans;
if(ancestor[0][temp1] != temp2)
ans = sum[t] * sum[temp2];
else
ans = (sum[1] - sum[temp1]) * sum[t];
cout << ans << endl;
--m;
}
return 0;
}
第四题暂时还没有做出来