简单题目:
Problem B.MST
解析:
这道题目看起来是在对树进行操作,但是仔细分析这是一个NP完全问题,对于最小,我们力求每次插入的都是最小的 g c d ( a , b ) gcd(a,b) gcd(a,b)权值,所以采用贪心法即可。对于素数来说,没什么好插的,但是对于合数来说,就会变得很好插入。比如18应该插在3的上面。这样最小公倍数就是3。
AC参考代码:
#include <cstring>
#include <iostream>
using namespace std;
int n;
unsigned long long ans = 0;
int prime[1000005]; //素数为1 约数为0
inline int read() { // Quick Read
register int s = 0, w = 1;
register char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') {
w = -1, ch = getchar();
}
}
while (ch >= '0' && ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * w;
}
int findMinx(int e) {
if (prime[e]) {
return 2 * e;
} else {
return e;
}
}
void quickEular(int);
int main() {
n = read();
quickEular(n);
for (int i = 3; i <= n; i++) {
// cout << i << ": " << findMinx(i) << " pri:" << prime[i] << endl;
ans += findMinx(i);
}
cout << ans;
return 0;
}
void quickEular(int n) { //快速筛选素数
int cnt = 0;
memset(prime, 1, sizeof(prime));
prime[2] = 1;
for (int i = 2; i <= n; i++) {
if (prime[i]) {
for (int k = 2; k * i <= n; k++)
prime[k * i] = 0; //约数 0
}
}
}
Problem G.出现次数
解析:
这道题目没啥好说的,注意范围给的空间比较宽裕,直接暴力就能AC。
暴力方法是,设置vec,当区间满足条件,就把这个区间加入到vec里面。
对于每一次的查询,查询本次查询的满足区间有多少个,输出答案即可。
AC代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int n, m, q;
string S, T;
typedef pair<int, int> pp;
vector<pp> vec;
int main() {
cin >> n >> m >> q;
cin >> S;
cin >> T;
for (int i = 0; i < n - m + 1; i++) {
if (T == string(&S[i], &S[i + m])) {
vec.push_back(pp(i, i + m - 1));
}
}
int l, r;
for (int i = 0; i < q; i++) {
cin >> l >> r;
l--;
r--;
int ans = 0;
for (auto it = vec.begin(); it != vec.end(); it++) {
if ((*it).first > r) {
break;
}
if ((*it).first >= l && (*it).second <= r) {
ans++;
}
}
cout << ans << endl;
}
return 0;
}
Problem E.染色
分析:
这道题目其实分析一下,也能立马得出答案。
对于优先级偏下的方块,如果先染色他,那么再次染色高优先级的方块,那么优先级偏下的方块颜色就消失了。我们要做的是,首先一定要先染色高优先级的方块,染色结束之后,再看看,附属于它的低优先级的方块要不要染色。
AC代码:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
typedef pair<int, int> pp; //<根节点,本节点>
int n, ans = 1; //自己根节点需要染色
int color[100005];
vector<pp> vec;
bool funcSort(const pp& p1, const pp& p2) {}
int main() {
cin >> n;
for (int i = 0; i < n - 1; i++) {
int x;
cin >> x;
vec.push_back(pp(x, i + 2));
}
for (int i = 0; i < n; i++) {
int x;
cin >> x;
color[i + 1] = x;
}
// sort()
for (auto it = vec.begin(); it != vec.end(); it++) {
if (color[(*it).second] != color[(*it).first]) {
ans++;
}
}
cout << ans;
return 0;
}
稍有难度:
Problem A.Area
解析:
虽然说,这只是稍有难度,其实还是很简单的。
利用微积分的思想,逐行扫描过去。当发现这个点包裹在图形内,那么就算这个点的面积也被三角形占用了。然后就这样扫描就好。
具体请看代码。
补充一点,判断M点是不是在以A,B,C点围成的三角形内的方法是:计算MA x MB
MB x MC MC x MA是不是同号的。
AC代码:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
typedef pair<double, double> pp;
#define step 0.003 //扫描步进尺度
int total = 0; //有多少符合的方块被扫描
int total1 = 0; //第一个三角形面积
int total2 = 0; //第二个三角形面积
bool dotVec(pp vec1, pp vec2) { // x1*y2-x2*y1 大于0返回true
if (vec1.first * vec2.second - vec2.first * vec1.second > 0) {
return true;
} else {
return false;
}
}
class Triangle {
private:
vector<pp> points; //点
vector<pp> _vecto; //向量
public:
Triangle();
Triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
this->points.push_back(pp(x1, y1));
this->points.push_back(pp(x2, y2));
this->points.push_back(pp(x3, y3));
this->_vecto.push_back(pp(x2 - x1, y2 - y1)); //顺时针存储。右手坐标系
this->_vecto.push_back(pp(x3 - x2, y3 - y2));
this->_vecto.push_back(pp(x1 - x3, y1 - y3));
}
bool onRange(pp point) { //判断这个点是不是在三角形的区域内
//需要在三角形每一个向量的右侧,即包含在内。(不计算包含在边的点)
pp PA = pp(points[0].first - point.first, points[0].second - point.second);
pp PB = pp(points[1].first - point.first, points[1].second - point.second);
pp PC = pp(points[2].first - point.first, points[2].second - point.second);
if (dotVec(PA, PB) == true && dotVec(PB, PC) == true && dotVec(PC, PA) == true) {
return true;
}
if (dotVec(PA, PB) == false && dotVec(PB, PC) == false && dotVec(PC, PA) == false) {
return true;
}
return false;
}
void outPut() { // Debug
for (auto it : this->_vecto) {
cout << it.first << " " << it.second << endl;
}
}
};
int main() {
int x1, y1, x2, y2, x3, y3;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
Triangle t1(x1, y1, x2, y2, x3, y3);
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
Triangle t2(x1, y1, x2, y2, x3, y3);
//扫描开始
for (double i = 0; i <= 9; i += step) {
for (double j = 0; j <= 9; j += step) {
bool inT1 = false, inT2 = false;
if (t1.onRange(pp(i, j))) {
total1++;
inT1 = true;
// cout << "in: (" << i << "," << j << ")" << endl;
}
if (t2.onRange(pp(i, j))) {
total2++;
inT2 = true;
}
if (inT1 && inT2) {
total++;
}
}
}
cout << fixed << setprecision(1) << (total1 + total2 - total) * step * step;
return 0;
}
总结:
本次比赛总共7题,小熊这个小菜鸡只解决了5道题目,太菜了呜呜呜。
继续加油吧!