湖南大学第十六届程序设计竞赛
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} Cm−1i(n1)i(nn−1