A. Aoe还是单体
1.题意
有n个怪物,怪物的血量为ai,有两个技能,一个是对一个怪物造成1点 伤害,消耗1点能量,另一个是对所有怪物造成一点伤害,消耗x点能量,求消灭所有怪物,最少消耗多少能量。
2.题解
把怪物的血量排下序,先用aoe击杀到正好剩x-1个怪物,然后剩下的全部用单体击杀。
3.代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 1e8+5;
ll n,x;
ll a[maxn];
int main(){
cin>>n>>x;
for(int i=1;i<=n;i++) {
cin>>a[i];
}
sort(a+1,a+1+n);
//2 3 4 5 6
ll ans=0;
if(n-x+1>0){
ans += a[n-x+1]*x;
for(int i=n-x+2;i<=n;i++)
ans += a[i] - a[n-x+1];
}
else {
for(int i=1;i<=n;i++)
ans += a[i];
}
cout<<ans<<endl;
return 0;
}
E. 点击消除
1.题意
给定一个由小写字母构成的字符串,如果两个字母相邻,则可以消除这两个字母,不限消除次数,输出字符串最终形态。
2.题解
用栈从后往前遍历字符串,栈为空或与栈顶字母不同则入栈,相同则弹出。
3.代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
string s;
stack<char> sk;
int main(){
cin>>s;
// abba
for(int i = s.size() - 1; i >= 0; i--) {
if(sk.empty() || s[i] != sk.top()) {
sk.push(s[i]);
} else {
sk.pop();
}
}
if(sk.empty()) {
puts("0");
} else {
while(!sk.empty()){
cout << sk.top();
sk.pop();
}
}
return 0;
}
F. 疯狂的自我检索者
1.题意
有n个人打分,分值为1分、2分、3分、4分和5分,有m个人将自己的打的分隐藏了起来,求平均分可能的最大值和最小值。
2.题解
水题。
3.代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e6+5;
int n,m,sum;
int a[maxn];
int main() {
cin>>n>>m;
for(int i = 1; i <= n-m; i ++) {
cin>> a[i];
sum += a[i];
}
double mmax = (sum + 5.0 * m) / (double)n;
double mmin = (sum + 1.0 * m) / (double)n;
printf("%.5f %.5f",mmin,mmax);
return 0;
}
G. 解方程
1.题意
x ^ a + b * lnx = c (1 <= x <= 3,1 <= b,c <= 1e9 ) ,求x,无解则输出-1。
2.题解
因为方程左边单调递增,所以用二分求解,x最小为1。注意用longdouble,否则会TLE。
3.代码
#include<bits/stdc++.h>
using namespace std;
#define ld long double
int a;
ld b,c;
ld binary(ld l, ld r) {
if(r - l <= 1e-8) {
return l;
}
ld mid = (r + l) / 2;
ld res = 1;
for(int i = 0; i < a; i++) {
res *= mid;
}
res += b * log(mid);
if(res < c) {
return binary(mid, r);
}
else {
return binary(l, mid);
}
}
int main() {
cin >> a >> b >> c;
printf("%.7Lf", binary(1, c));
return 0;
}
H. 神奇的字母(二)
1.题意
给定一段话,由小写字母和空格构成,输出出现字母最多的那个字母。
2.题解
水题,用个数组记录次数即可。
3.代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 1e8 + 5;
int a[200];
int main() {
string s;
while(cin >> s) {
//cout<<s<<endl;
for(int i = 0; i < s.size(); i++) {
a[s[i]]++;
}
}
int mmax = 0;
int pos = 0;
for(int i = 'a'; i <= 'z'; i++) {
if(a[i] > mmax) {
mmax = a[i];
pos = i;
}
}
char ans = pos;
cout << ans << endl;
return 0;
}
I. 十字爆破
1.题意
给定一个n * m的矩阵,输出一个n * m的矩阵。对应位置是同行与同列元素之和。
2.题解
预处理,将每列与每行的和分别存在一个数组里。(注意输入与输出数据比较大,最好用scanf输入,或者用ios::sync_with_stdio(false);语句加快cin输入)
3.代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 1e6 + 5;
ll n,m;
ll a[maxn], row[maxn], col[maxn];
int main() {
ios::sync_with_stdio(false);
cin >> n >> m;
int k = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cin >> a[k];
row[i] += a[k];
col[j%m] += a[k];
k++;
}
}
k = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(!j)
cout << (row[i] + col[j] - a[k++]);
else
cout << ' ' << (row[i] + col[j] - a[k++]);
}
cout << endl;
}
return 0;
}