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; }