寒假题单-题解
寒假题解
Zy的白日梦
思路
商品的总金额计算完后再进行抹零。
可以使用数组存储所有数据,再判断;亦可直接输入判断,用变量 \(vip\) 表示是否为会员,如果是会员,则每件物品打对应的折扣。
输入时注意是小数输入,输出保留小数点后 \(3\) 位。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int N, p, vip;
double ans, x, y, sum;
int main(){
cin >> N;
while(N--) {
cin >> p >> vip;
sum = 0.0;
for (int i = 0; i < p; ++i) {
cin >> x >> y;
if (vip) sum += x * y;
else sum += x;
}
ans += (sum * 10 - int(sum * 10)) / 10;
}
cout << fixed << setprecision(3) << "$" << ans << endl;
return 0;
}
Zy的宝藏
思路
考察数学,若模拟,只能拿到部分,观察前几项得到规律或者推导出来。
第 \(i\) 次,将所有 \(i\) 的倍数米切换状态。
所以,对于第 \(k\) 米状态,它切换的次数恰好是 \(k\) 的约数的个数。如果 \(k\) 有偶数个约数,那么最后第 \(k\) 米一定没有埋下宝箱。如果 \(k\) 有奇数个约数,则第 \(k\) 米一定埋下宝箱。
那么 \(k\),如果有约数 \(x\),则一定有约数 \(\frac{k}{x}\)。若 \(x^2 \neq k\),约数都是成对出现的。说明,只有当 \(k\) 是完全平方数时候,它会有奇数个约数,否则一定有偶数个约数。
因此找出 \(1,2,..N\) 中的完全平方数的个数即可,答案为 \(\lfloor \sqrt{n} \rfloor\)。
代码
#include <bits/stdc++.h>
using namespace std;
int N;
int main(){
cin >> N;
cout << (int)sqrt(N);
return 0;
}
数字缩水
思路
注意数据大小 \(10^{1000}\),\(1000\) 位的整数,需要将整数作为字符串处理。
贪心算法,策略:每一次删除一位要使得随后得到的整数为最大,高位数字应该继续保持高位,因此寻找最小数字不可行。
例如:\(3241\),若寻找最小值 \(1\),得到 \(324\) 小于取 \(2\) 删除后的数字 \(341\)。
因此最佳的策略:从左向右寻找第一个小于右侧数字,删除此数字一定为最大,若没有找到,那么删除最后一位保持所有高位(除个位以外)均最大。
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int main(){
cin >> s;
// 循环输出 m - 1 次删除后的整数
for (int m = s.length(); m >= 1; --m) {
bool isok = false;
int deletes;
// 寻找第一个小于右侧的数字,若存在直接删除这个位置上的数字,否则删除最后一位
for (int j = 0; j < s.length() - 1; ++j) {
if (s[j] < s[j + 1]) {
deletes = j;
isok = true;
break;
}
}
// 删除数字
if (isok) s.erase(deletes, 1);
else s.erase(s.length() - 1);
cout << s << endl;
}
return 0;
}
【寒假-特别题目】最小字符串
思路
字符串sort排序即可,最后依次输出。
代码
#include <bits/stdc++.h>
using namespace std;
string ss[505];
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> ss[i];
}
sort(ss + 1, ss + n + 1);
for (int i = 1; i <= n; i++) {
cout << ss[i];
}
return 0;
}
【寒假-特别题目】是否有下一个身份
思路
下一个全排列可以使用 \(next\)_\(permutation()\) 函数获取,当然可以自行写出\(O(N)\)下一个全排列的代码。
代码
#include <bits/stdc++.h>
using namespace std;
string s, r;
int main() {
while (cin >> s) {
if (s == "#") break;
r = s;
next_permutation(s.begin(), s.end()); // 下一个全排列,在原字符串基础上修改
if (s > r) cout << s << nl;
else cout << "BOSS" << nl;
}
return 0;
}
【寒假-特别题目】寻找中位数
思路
快速排序取需要找的区间继续划分或 \(nth\)_\(element()\) 函数求得第 \(k\) 个数字,会将该区间数据重新排列,前 \(k - 1\) 个数字均小于等于第 \(k\) 个数字,后面的所有数字均大于等于第 \(k\) 个数字。
代码
#include <bits/stdc++.h>
using namespace std;
vector<long long> v;
int n;
int main() {
cin >> n;
while (n--) {
long long x;
cin >> x;
v.push_back(x);
long long ans = 0, midden = v.size() / 2; // 中位数的位置
nth_element(v.begin(), v.begin() + midden, v.end());
ans += v[midden];
// 若是偶数个,需要再加上一个中位数的和除以二
if (v.size() % 2 == 0) {
nth_element(v.begin(), v.begin() + midden - 1, v.end());
ans = (ans + v[midden - 1]) / 2;
}
cout << ans << nl;
}
return 0;
}

浙公网安备 33010602011771号