太久没写博客了,感觉做的题不自己写一遍思路总还是有点问题。。。
又到了新年啦,cf的新年特效爱了爱了
A. Cut the Triangle
给出三角形的三个顶点坐标,问是否可以使用水平或者竖直线从任意一个顶点将三角形划为两部分。
思路:易得知,只有直角三角形不能满足条件,而且必须是直角边与坐标轴垂直的直角三角形,根据性质判断即可。
AC Code:
#include <bits/stdc++.h>
typedef long long ll;
const int N = 1e5 + 5;
int t;
int x[5], y[5];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> t;
while(t --) {
std::map<int, int> mpx, mpy;
for(int i = 1; i <= 3; i ++) {
std::cin >> x[i] >> y[i];
mpx[x[i]] ++, mpy[y[i]] ++;
}
int cntx = 0, cnty = 0;
for(auto [x, y] : mpx) {
if(y >= 2) cntx ++;
}
for(auto [x, y] : mpy) {
if(y >= 2) cnty ++;
}
if(cntx && cnty)
std::cout << "NO" << '\n';
else
std::cout << "YES" << '\n';
}
return 0;
}
B. Block Towers
给出一个数组,对于数组中的两个数i,j,只有a[i] < a[i]时,可以将a[i] + 1, a[j] - 1,问这样操作任意次,a[1]能达到的最大值是多少。
思路:因为是对于a[2] ~ a[n]操作,为了每个数最大化利用,我们将这一段内的数升序排序,直接计算即可。
AC Code:
#include <bits/stdc++.h>
typedef long long ll;
const int N = 2e5 + 5;
int t, n;
ll a[N];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> t;
while(t --) {
std::cin >> n;
for(int i = 1; i <= n; i ++) {
std::cin >> a[i];
}
std::sort(a + 2, a + 1 + n);
for(int i = 2; i <= n; i ++) {
if(a[i] <= a[1]) continue;
ll res = a[i] + a[1] - (a[i] + a[1]) / 2;
a[1] = res;
}
std::cout << a[1] << '\n';
}
return 0;
}
D. Playoff
给出1 ~2^n的排列,每次两两对战,给出n次比赛的结果,0表示数字小者胜,1表示数字大者胜,问n次对战后,哪些数字可以胜出。
思路:容易想到,最后胜出的一定是连续的数字中的一个,所以可以考虑解决这个区间的两个极值。对于极小值x,若遇见0的情况,那需要一个大于x的值对战,而这个值能到此次对战需要更多小于它的数字,所以会用到大于x的一些值;反之,在遇见1的情况,那需要一个小于x的值,且这个值在之前所有结局为1的条件下胜出,则会用到小于x的部分数字。可以假设之前结局为1的回合是cnt,那么一共需要2^cnt个能力低者。对于极大值,与此分析类似。
AC Code:
#include <bits/stdc++.h>
typedef long long ll;
const int N = 105;
const int mod = 998244353;
int t, n;
std::string s;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> n >> s;
s = ' ' + s;
int min = 0, max = 0;
int cnt1 = 0, cnt0 = 0;
for(int i = 1; i <= n; i ++) {
if(s[i] == '1') {
min += (ll)1 << cnt1;
cnt1 ++;
}
else
cnt0 ++;
}
int l = min + 1;
cnt1 = cnt0 = min = max = 0;
for(int i = 1; i <= n; i ++) {
if(s[i] == '0') {
max += (ll)1 << cnt0;
cnt0 ++;
}
else
cnt1 ++;
}
int r = (1 << n) - max;
for(int i = l; i <= r; i ++) {
std::cout << i << " \n"[i == r];
}
return 0;
}
os:思维思维!想明白了还是挺好写的