2020 HDU Multi-University Training Contest 1(部分)

6754 Distinct Sub-palindromes

找规律 从长度为4开始的串就一样了

#include<cstdio>
using namespace std;
int main(void) {
	int T, n;
	scanf("%d", &T);
	while (T--) {
		scanf("%d", &n);
		if (n == 1)printf("26\n");
		else if (n == 2)printf("676\n");
		else if (n == 3)printf("17576\n");
		else printf("15600\n");
	}
	return 0;
}

6755 Fibonacci Sum

题解:https://blog.csdn.net/u014609452/article/details/53039223

#include<cstdio>
using namespace std;
typedef long long ll;
const ll p = 1e9 + 9;
const ll InvSqrt5 = 276601605;
const ll A = 691504013;//1+根号5 / 2
const ll InvA = 691504012;
const ll B = 308495997;//1-根号5 / 2
const ll InvB = 308495996;
const int maxk = 1e5 + 5;
ll pa[maxk], pb[maxk], inv[maxk], fac[maxk];
ll ksm(ll a, ll n) {
    ll ret = 1;
    while (n) {
        if (n & 1)ret = (ret * a) % p;
        a = (a * a) % p;
        n >>= 1;
    }
    return ret % p;
}
ll Cnm(int n, int m) {
    return fac[n] * inv[m] % p * inv[n - m] % p;
}
ll Inv(ll x) {
    return ksm(x, p - 2);
}
ll ans, N, C;
int T, K;
int main(void) {
    pa[0] = pb[0] = fac[0] = 1;
    for (int i = 1; i < maxk; i++) fac[i] = fac[i - 1] * i % p;
    inv[1] = 1;
    for (int i = 2; i < maxk; i++) inv[i] = (p - p / i) * inv[p % i] % p;
    inv[0] = 1;
    for (int i = 1; i < maxk; i++) inv[i] = inv[i] * inv[i - 1] % p;
    for (int i = 1; i < maxk; i++) {
        pa[i] = pa[i - 1] * A % p;
        pb[i] = pb[i - 1] * B % p;
    }
    scanf("%d", &T);
    while (T--) {
        scanf("%lld %lld %d", &N, &C, &K);
        C = C % (p - 1);
        ll N2 = N % (p - 1);
        ll InvAC = ksm(InvA, C);
        ll BC = ksm(B, C);
        ans = 0;
        ll t = ksm(pa[K + 1] * InvB % p, C);
        for (ll r = 0; r <= K; r++) {
            t = t * BC % p * InvAC % p;
            ll tmp = t == 1 ? (N % p) : (t * (ksm(t, N2) - 1 + p) % p * Inv(t - 1) % p);
            tmp = Cnm(K, r) * tmp % p;
            if (r & 1)tmp = (p - tmp) % p;
            ans = (ans + tmp) % p;
        }
        ans = ans * ksm(InvSqrt5, K) % p;
        printf("%lld\n", ans);
    }
    return 0;
}

6759 Leading Robots

半平面交裸题+1

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
const double INF = 1e12;
const double eps = 1e-8;
map<pair<double, double>, int>id;
bool no[50005];
int sgn(double x) {
    if (fabs(x) < eps)return 0;
    else return x < 0 ? -1 : 1;
}
struct Point {
    double x, y;
    Point() {}
    Point(double x, double y) :x(x), y(y) { }
    Point operator + (Point B) { return Point(x + B.x, y + B.y); }
    Point operator - (Point B) { return Point(x - B.x, y - B.y); }
    Point operator * (double k) { return Point(x * k, y * k); }
};
typedef Point Vector;
double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }//叉积
struct Line {
    Point p;
    Vector v;
    double ang;
    bool chong;
    Line() {}
    Line(Point p, Vector v, bool chong = false) :p(p), v(v), chong(chong) { ang = atan2(v.y, v.x); }
    bool operator < (Line& L) { return ang < L.ang; }
};
bool OnLeft(Line L, Point p) { return sgn(Cross(L.v, p - L.p)) > 0; }
Point Cross_Point(Line a, Line b) {
    Vector u = a.p - b.p;
    double t = Cross(b.v, u) / Cross(a.v, b.v);
    return a.p + a.v * t;
}
vector<Point>HPI(vector<Line>& L) {
    int n = L.size();
    sort(L.begin(), L.end());
    int first, last;
    vector<Point>p(n);
    vector<Line>q(n);
    vector<Point>ans;
    q[first = last = 0] = L[0];
    for (int i = 1; i < n; i++) {
        while (first < last && !OnLeft(L[i], p[last - 1])) {
            last--; no[last] = false;
        }
        while (first < last && !OnLeft(L[i], p[first]))first++;
        q[++last] = L[i];
        if (L[i].chong)no[last - 1] = true;//接下来的点会是重合点
        if (fabs(Cross(q[last].v, q[last - 1].v)) < eps) {
            last--;
            no[last] = false;
            if (OnLeft(q[last], L[i].p)) {//如果左边的直线是L[i]
                if (L[i].chong)no[last - 1] = true;
                q[last] = L[i];
            }
        }
        if (first < last)p[last - 1] = Cross_Point(q[last - 1], q[last]);
    }
    while (first < last && !OnLeft(q[first], p[last - 1])) {
        last--; no[last] = false;
    }
    if (last - first <= 1) {
        ans.resize(2);
        return ans;
    }
    p[last] = Cross_Point(q[last], q[first]);
    for (int i = first; i <= last; i++) {
        if (no[i])continue;
        ans.push_back(p[i]);
    }
    return ans;
}
int main(void) {
    int T, n;
    scanf("%d", &T);
    while (T--) {
        id.clear();
        memset(no, 0, sizeof(no));
        scanf("%d", &n);
        vector<Line>L;
        L.push_back(Line(Point(0, 0), Vector(0, -1)));
        L.push_back(Line(Point(0, INF), Vector(-1, 0)));
        while (n--) {
            double a, b;
            scanf("%lf%lf", &a, &b);
            pair<double, double>tmp(a, b);
            if (id.count(tmp)) {
                L[id[tmp]].chong = true;
                continue;
            }
            L.push_back(Line(Point(0, a), Vector(1, b)));
            id[tmp] = L.size() - 1;
        }
        vector<Point>ans = HPI(L);
        printf("%d\n", ans.size() - 2);
    }
    return 0;
}

6762 Mow

看题意可以知道需要计算圆可以占据的最大面积
借用其它博文的图,由图可知面积为:小多边形的面积+周长*r+π*r^2
步骤:读入直线->直线向内平移r个单位长度->半平面交求点->计算多边形面积/周长

来源于https://blog.csdn.net/hjp965329780/article/details/107556179

#include<cstdio>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cmath>
const double pi = acos(-1);
const double eps = 1e-8;
using namespace std;
int sgn(double x) {
	if (fabs(x) < eps)return 0;
	else return x < 0 ? -1 : 1;
}
struct Point{
	double x, y;
	Point(){}
	Point(double x, double y) :x(x), y(y) {}
	Point operator + (Point B) { return Point(x + B.x, y + B.y); }
	Point operator - (Point B) { return Point(x - B.x, y - B.y); }
	Point operator * (double k) { return Point(x * k, y * k); }
	Point operator / (double k) { return Point(x / k, y / k); }
	Point turn90() { return Point(-y, x); }//逆时针转90度
	Point unit() { return Point(x / len(), y / len()); }
	double len() { return sqrt(x * x + y * y); }
};
typedef Point Vector;
inline double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }
inline double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }
inline double pow2(double x) { return pow(x, 2); }
inline double dis(Point A, Point B) { return sqrt(pow2(A.x - B.x) + pow2(A.y - B.y)); }
struct Line{
	Point p;
	Vector v;
	double ang;
	Line(){}
	Line(Point p, Vector v) :p(p), v(v) { ang = atan2(v.y, v.x); }
	bool operator < (const Line& L) { return ang < L.ang; }
	void translation(double dis) {
		p = p + v.turn90().unit() * dis;
	}
};
inline bool OnLeft(Line L, Point p) { return sgn(Cross(L.v, p - L.p)) > 0; }
inline Point Cross_point(Line a, Line b) {
	Vector u = a.p - b.p;
	double t = Cross(b.v, u) / Cross(a.v, b.v);
	return a.p + a.v * t;
}
inline double Polygon_area(vector<Point>& p, int n) {
	double area = 0;
	for (int i = 0; i < n; i++)
		area += Cross(p[i], p[(i + 1) % n]);
	return area / 2;
}
vector<Point>HPI(vector<Line>L) {
	int n = L.size();
	sort(L.begin(), L.end());
	int first, last;
	vector<Point>p(n);
	vector<Line>q(n);
	vector<Point>ans;
	q[first = last = 0] = L[0];
	for (int i = 1; i < n; i++) {
		while (first < last && !OnLeft(L[i], p[last - 1]))last--;
		while (first < last && !OnLeft(L[i], p[first]))first++;
		q[++last] = L[i];
		if (fabs(Cross(q[last].v, q[last - 1].v)) < eps) {
			last--;
			if (OnLeft(q[last], L[i].p))q[last] = L[i];
		}
		if (first < last)p[last - 1] = Cross_point(q[last - 1], q[last]);
	}
	while (first < last && !OnLeft(q[first], p[last - 1]))last--;
	if (last - first <= 0)return ans;
	p[last] = Cross_point(q[last], q[first]);
	for (int i = first; i <= last; i++)ans.push_back(p[i]);
	return ans;
}
inline double perimeter(vector<Point>& p, int n) {
	double res = 0;
	for (int i = 0; i < n; i++)
		res += dis(p[i], p[(i + 1) % n]);
	return res;
}
const int N = 210;
int T, n, r, A, B;
vector<Point> p;
vector<Line> l;
int main(void) {
	//freopen("in.txt", "r", stdin);
	scanf("%d", &T);
	while (T--) {
		scanf("%d%d%d%d", &n, &r, &A, &B);
		p.resize(n); l.resize(n);
		for (int i = 0; i < n; i++)
			scanf("%lf%lf", &p[i].x, &p[i].y);
		double area = Polygon_area(p, n);
		if (sgn(area) < 0) {//点可能是逆时针也可能是顺时针输入
			reverse(p.begin(), p.end());
			area *= -1;
		}
		double ans = area * A;
		if (A <= B) {
			printf("%.12f\n", ans);
			continue;
		}
		for (int i = 0; i < n; i++) {
			l[i] = Line(p[i], p[(i + 1) % n] - p[i]);
			l[i].translation(r);
		}
		p = HPI(l);
		double area2 = Polygon_area(p, p.size()) + perimeter(p, p.size()) * r + pi * r * r;
		if(p.size())ans = min(ans, fabs((area - area2) * A + area2 * B));
		printf("%.12f\n", ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JILIN.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值