以下代码只给出solve()
A. Square
题目解释:随机给定一个正方形在坐标轴中的四个坐标,求面积。
题解:因为其正方形的边是平行于坐标轴的,直接求其边长即可。
代码:
void solve() {
vector<ll>a(8);
for (int i = 0;i < 8;i++) {
cin >> a[i];
}
ll x = a[0] == a[2] ? abs(a[1] - a[3]) : abs(a[0] - a[2]);
cout << x * x << endl;
}
B. Arranging Cats
题目解释:给两个字符串s,target,在给定的三种步骤下将s转化为target,求min的次数将s->target.
题解:给出了三种步骤,其中可以将s[i]=‘1’,s[j]=‘0’两个互换为s[i]=‘0’,s[j]=‘1’,毫无疑问这一步骤要最大化,运用尽可能多次,就是贪心思想,然后最后在考虑将其翻转为‘0’或‘1’。
我这里用了unordered_map这样的数据结构来存储s中‘1’的索引,在遍历过程中cnt记录target[i]=='1'并且i也不在mp中的个数,并将s[i]==target[i]==‘1’的i从mp中移除,最后min(cnt,mp.size())即为可以用最贪心的步骤的次数,abs(cnt-mp.size())即为不能用的次数。
代码:
void solve() {
int n;
cin >> n;
string s, target;
cin >> s;
cin >> target;
if (s == target) {
cout << 0 << endl;
return;
}
unordered_map<int,int>mp;
for (int i = 0;i < n;i++) {
auto c = s[i];
if (c == '1')mp[i] = 1;
}
ll cnt = 0;
for (int i = 0;i < n;i++) {
if (target[i] == '1') {
if (mp.count(i)) {
mp.erase(i);
continue;
}
else {
cnt++;
}
}
}
ll ans = min(cnt, ll(mp.size()))+abs(cnt-ll(mp.size()));
cout << ans << endl;
}
C. Sending Messages
题目解释:给定起始电量,每短时间所耗费的电量,开关机所耗费的电量,一个数组moments,必须在moments[i]时开机,问是否能打完所有电话
题解:也是贪心思想,总电量 - 从此时刻到下一打电话时刻所耗费的min电量,要么关机开机,要么什么也不做,看每一时刻f是否>0即可
void solve() {
int n;
ll a, b, f;
cin >> n>>f>>a>>b;
vector<ll>moments(n);
for (int i = 0;i < n;i++) {
cin >> moments[i];
}
f -= min(moments[0]*a, b);
if (f <= 0) {
cout << "NO\n";
return;
}
for (int i = 1;i < n;i++) {
f -= min(a*(moments[i]-moments[i-1]), b);
if (f <= 0) {
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
D. Very Different Array
题目解释:给定两个数组a,b求其∑(i,n)=|ai−bi|的最大值
题解:将其排序,也是用贪心思想,要么是|a最大值-b最小值|或|a最小值-b最大值|,取其max即可
代码:
int n,m;
void solve() {
cin >> n >> m;
vector<ll>a(n), b(m);
for (auto& x : a) {
cin >> x;
}
for (auto& x : b) {
cin >> x;
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
ll ans = 0;
int l_a = 0, r_a = n - 1;
int l_b = 0, r_b = m - 1;
while (l_a<=r_a) {
if (abs(a[l_a] - b[r_b]) >= abs(a[r_a] - b[l_b])) {
ans += abs(a[l_a++] - b[r_b--]);
}
else {
ans += abs(a[r_a--] - b[l_b++]);
}
}
cout << ans << endl;
}
E. Eat the Chip
题目解释:Alice(A),Bob(B),在一棋盘上,A先动,每次只能向下、左下、右下移动,B与其相反。如果轮到A,并且A可以移动到B的位置,A赢,反之B赢。如果A移动到最下方,或B移动到最上方,平局(也就是轮到谁不能动了,就平局)。
题解:博弈问题,特殊情况,当A在B的同一行或下方时两人平局。
当两人竖向距离为偶数时,A可能赢,奇数时,B可能赢。
当A可能赢时,B要向远离A的横向距离移动,判断最后B移动到远离A的方向的尽头时,A是否能在两人错过之前到达,如果可以,那A就赢,否则平局。
当B可能赢时,我们只需要将B转化为先移动者,将A的位置预先处理下,然后按照上述方法处理即可。
void solve() {
ll h, w, xa, ya, xb, yb;
cin >> h >> w >> xa >> ya >> xb >> yb;
if (xa >= xb) {
cout << "Draw\n";
return;
}
if ((xb-xa-1) % 2 == 0) {
if (abs(ya - yb) <= 1) {
cout << "Alice\n";
return;
}
if (ya > yb) {
//A:右,B:左
if (ya - 1 <= (xb - xa + 1) / 2) {
cout << "Alice\n";
return;
}
else {
cout << "Draw\n";
return;
}
}
else {
if (w - ya <= (xb - xa + 1) / 2) {
cout << "Alice\n";
return;
}
else {
cout << "Draw\n";
return;
}
}
}
else {
if (ya == yb) {
cout << "Bob\n";
return;
}
if (ya > yb) {
ya = min(w, ya + 1);
xa++;
}
else {
ya = max(1ll, ya - 1);
xa++;
}
if (ya < yb) {
if (yb - 1 <= (xb - xa + 1) / 2) {
cout << "Bob\n";
return;
}
else {
cout << "Draw\n";
return;
}
}
else {
if (w - yb <= (xb - xa + 1) / 2) {
cout << "Bob\n";
return;
}
else {
cout << "Draw\n";
return;
}
}
}
}