题意:
就是有很多个东西会在同一个点上,你可以选择花一块钱消灭一个东西,也可以选择花c块钱消灭一个点上的所有东西,问你最少花多少钱可以消灭所有点的东西。
思路:
就看看是花一块钱一个个消灭的钱少,还是c块钱消灭所有的钱少。
#include<iostream>
#include<vector>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<cmath>
#include<stack>
#include<algorithm>
#include<queue>
#include<map>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int counts[105];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
memset(counts, 0, sizeof(counts));
int n, c;
cin >> n >> c;
for (int i = 1; i <= n; i++)
{
int num;
cin >> num;
counts[num]++;
}
int res = 0;
for (int i = 0; i <= 100; i++)
{
res += min(counts[i], c);
}
cout << res << endl;
}
return 0;
}
B.Meeting on the Line
这题是真尼玛抽象……
题意:
给出每个人的位置xi和每个人的穿衣时间ti,让你求一个位置,使得所有人中花费时间最多的这个人,花费的时间最小。
题解:
用二分法,但位置不好二分,不一定具有单调性。所以二分时间。假设二分的这个时间T,是所有人花费时间中的最大值。
那么根据题意就有ti+|xi-x0|<=T,即ti+xi-T<=x0<=T+xi-ti。如果所有人的x0范围有交集,那么选取的这个时间T就是合法的。
#include<iostream>
#include<vector>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<cmath>
#include<stack>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<map>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn], b[maxn];
double ans = 0;
bool check(double mid,int n)
{
double l = -1e9, r = 1e9;
for (int i = 1; i <= n; i++)
{
if (mid < b[i])
return false;
else
{
l = max(l, a[i] + b[i] - mid);
r = min(r, a[i] + mid - b[i]);//求区间交集
}
}
ans = l;
return r+(1e-8) >= l;//允许的误差
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
double l = 0, r = 1e9;
for (int i = 0; i < 100; i++)
{
double mid = (l + r) / 2;
if (check(mid,n))
r = mid;
else
l = mid;
}
check(l,n);//需要求出位置
cout <<std::fixed<<setprecision(7) << ans<< endl;
}
return 0;
}
C. Minimum Notation
题意:
给你一串数字,你可以选择让一个数字d变成min(d+1,9),然后让它插在任意一个位置,让你通过这种操作变出一个字典序最小的数字串。
思路:
通过题目所给的操作,不会让数字变小,所以要将原本数字串中,小的放在前面。比如04829,要将2插在0后面,就需要把4和8变成5和9然后随便放在一个位置,所以先不用管5和9,等最后输出答案的时候,在按字典序输出就行了。
#include<iostream>
#include<vector>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<cmath>
#include<stack>
#include<algorithm>
#include<queue>
#include<map>
#define int long long
using namespace std;
const int maxn = 1e5 + 5;
int counts[maxn];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
queue<int> num[10];
string s;
cin >> s;
for (int i = 0; i < s.length(); i++)
num[s[i] - '0'].push(i);
string ans = "";
string pre = "";
for (int i = 0; i <= 9; i++)
{
while (!num[i].empty())
{
int l = num[i].front();
for (int j = i+1; j <= 9; j++)
{
while (!num[j].empty()&&num[j].front() < l)
pre = pre + (char)(min(j+1,1LL*9) + '0'), num[j].pop();
}
ans = ans + (char)(i + '0');
num[i].pop();
}
}
ans = ans + pre;
sort(ans.begin(), ans.end());
cout << ans << endl;
}
return 0;
}