训练实录 | 湖南大学第十六届程序设计竞赛

本文记录了湖南大学第十六届程序设计竞赛的解题过程,涉及A到L共12道题目。解题者分享了各题目的思路和解决方案,包括三角形判断、序列变换、队列问题、窗口概率计算、团队计算、字符串操作等,通过动态规划、二分查找、 BFS 等算法解决复杂问题。
摘要由CSDN通过智能技术生成

湖南大学第十六届程序设计竞赛

传送门

A - Triangles

solved by Micky. 00:38:55(+2)

题意: 水题,给三个点的坐标,判断是(钝角,锐角,直角,非)三角形。

#include <string>
#include <queue>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <set>
#include <map>
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
typedef long double ld;
const int maxn = 1e3 + 9, inf = 0x3f3f3f3f;
const long long MOD = 1e9 + 7;
long double esp = 1e-10;
long long int n, m, t, k, a[maxn], dis[maxn][maxn], d[maxn][maxn];
int vis[maxn];


double len(double x1, double y1, double x2, double y2) {
   
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}


double countcos(double a, double b, double c) {
   
	return (a * a + b * b - c * c) / (2 * a * b);
}

int main() {
                 //+++++++++++++++++++++++++++++++++
	cin.tie(0); std::ios::sync_with_stdio(false);
	cin >> n;
	for (int i = 0; i < n; i++) {
   
		double x1, y1, x2, y2, x3, y3;
		cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
		double a1 = len(x1, y1, x2, y2), b1 = len(x1, y1, x3, y3), b3 = len(x2, y2, x3, y3);
		if (fabs(a1 + b1 - b3) < 1e-9 || fabs(a1 + b3 - b1) < 1e-9 || fabs(b3 + b1 - a1) < 1e-9) {
   
			cout << "invalid" << endl;
			continue;
		}
		double ab = countcos(a1, b1, b3), ac = countcos(b3, a1, b1), cb = countcos(b3, b1, a1);

		if (fabs(ab) < 1e-9 || fabs(ac) < 1e-9 || fabs(cb) < 1e-9) {
   
			cout << "right" << endl;
			continue;
		}
		if (ab < 0 || ac < 0 || cb < 0) {
   
			cout << "obtuse" << endl;
			continue;
		}
		if (ab > 0 && ac > 0 && cb > 0) {
   
			cout << "acute" << endl;
			continue;
		}
	}
	return 0;
}

B - Yuki with emofunc and playf

solved by Micky(after)

题意:
对于一个数k有两种变换,将k变成10*k,或将k变成x-1+k。
现给出n与x,问从k=1开始,k至少要经过几次变换才能让k满足k%n==0。

思路:首先要明白,对于加与乘运算来说,取模后在运算 或是 运算后再取模 结果都是一样的。
所以我们可以再运算的过程中直接取模。这样可以减少数据,最大取模是取模1e6,所以可以把数据控制再小于1e6。
那么对于上面两种运算就变成了,k=(10*k)%n, k=(x-1+k)%n。
这里有一个数组times[i]表示k变为满足k%n==i所需的运算次数。那么我们要求的就是times[0]。
在用一个vis数组把出现过的k的标记一下,就可以控制时间复杂度在O(n)。
然后再跑一边bfs,往两种运算分别寻找。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
#define ll long long

const int maxn = 1e6 + 9, inf = 0x3f3f3f3f;
int vis[maxn], n, x, times[maxn];
queue<int>q;

int bfs(int start) {
   
	for (int i = 0; i < maxn; i++)times[i] = inf;
	q.push(start);
	times[1] = 0;
	vis[start] = 1;
	while (!q.empty()) {
   
		int temp = q.front();
		q.pop();
		long long nxt1 = (temp * 10) % n, nxt2 = (temp + x - 1) % n;
		if (!vis[nxt1]) {
   
			q.push(nxt1);
			times[nxt1] = min(times[temp] + 1, times[nxt1]);
			vis[nxt1] = 1;
		}
		if (!vis[nxt2]) {
   
			q.push(nxt2);
			times[nxt2] = min(times[temp] + 1, times[nxt2]);
			vis[nxt2] = 1;
		}
	}
	if (times[0] != inf)return times[0];
	return -1;
}

int main() {
   
	cin >> n >> x;
	if (n == 1) {
   
		cout << 0;
		return 0;
	}
	cout << bfs(1);
	return 0;
}

D - Queuing

solved by oye. (after)

题意:

贴两篇目前看到的唯二的题解:题解1 题解2
没别的想法,当事人赛后看到代码很震惊 : ) ——Yuki Sam


Hihi,这里是比赛时写错公式的oye,导致打表找规律都不能找。
现在就讲一下思路,题目意思是有m个人,n个窗口,每个人的顺序都是定好的,我们要求主人公的期望排名,由于主人公是最后一个,所以在队伍里永远都是排最后的。每个人去某个窗口的概率是 1 n \frac{1}{n} n1
假定主人公去某一个窗口(窗口都是一样的,所以不用考虑去哪个窗口,我们只考虑主人公前面排几个人)。假设有i个人排在他前面,那么这个概率为 C m − 1 i ( 1 n ) i ( n − 1 n ) m − 1 − i C^i_{m-1}(\frac{1}{n})^i(\frac{n-1}{n})^{m-1-i} Cm1i(n1)i(nn1

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值