2016 Multi-University Training Contest 3

本文精选了多项算法竞赛题目并提供了详细的解决方案,包括数学运算、概率计算、棋盘策略、几何问题、点对分析等内容,适合算法爱好者学习参考。

先扔这以后再补吧,神马比赛都是浮云。。。
A
题意:就是问n能否开k次根号得到1,其中k <= 5。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const int MAXM = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
char str[110];
int main()
{
    //LL n = 4294967295;
    //printf("%d\n", (int)sqrt(n*1.0));
    while(scanf("%s", str) != EOF) {
        int len = strlen(str);
        if(len > 10) {
            printf("TAT\n");
            continue;
        }
        LL n = 0;
        for(int i = 0; i < len; i++) {
            n = n * 10 + (str[i] - '0');
        }
        if(n > 4294967295 || n == 0) {
            printf("TAT\n");
            continue;
        }
        int ans = 0;
        while(n != 1) {
            n = (LL)sqrt(n * 1.0);
            ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}

B
定义一个序列 h[] 的价值为: ni=1(a[i](h[i]>h[i1] && h[i]>h[i+1]))
题意:求 1n 序列价值的期望。
考虑每个元素所在的位置,统计一下。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const int MAXM = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int a[1001];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF) {
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        if(n == 1) {
            printf("%.6lf\n", a[1] * 1.0);
            continue;
        }
        double ans = 0;
        for(int i = 2; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(j == 1 || j == n) {
                    ans += 1.0 / n * 1.0 / (n - 1) * (i - 1) * a[j];
                }
                else if(i > 2) {
                    ans += 1.0 / n * 1.0 / (n - 1) * 1.0 / (n - 2) * (i - 1) * (i - 2) * a[j];
                }
            }
        }
        printf("%.6lf\n", ans);
    }
    return 0;
}

C
题意:给定一个n*m国际象棋棋盘,两个人都采取最优策略问王、王后、车、马谁可以从(1, 1)先到达(n, m)。

思路:
王后的话可以看做是一个威佐夫博奕,
马的话直接列方程求出横竖需要走的次数,当次数绝对值大于1时肯定no winner,等于1时先手赢,反之输。
车的话可以看做是一个尼姆博奕。
王的话就是一个巴什博弈。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
const int MAXN = 2 * 1e5 + 10;
const int MAXM = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int main()
{
    int t;scanf("%d",&t);
    while(t--) {
        int op, n, m; scanf("%d%d%d", &op, &n, &m);
        if(op == 4) {
            n--, m--;
            if(n < m) swap(n, m);
            int k = n - m;
            n = (int)(k * (1 + sqrt(5.0)) / 2.0);
            if(n == m) printf("G\n");
            else printf("B\n");
        }
        else if(op == 3) {
            if((n + m - 2) % 3) printf("D\n");
            else {
                int r = (2 * m - n - 1) / 3, d = (2 * n - m - 1) / 3;
                if(abs(r - d) >= 2)
                    printf("D\n");
                else if(abs(r - d) == 1)
                    printf("B\n");
                else
                    printf("G\n");
            }
        }
        else if(op == 2) {
            int ans = 0;
            ans ^= (n - 1); ans ^= (m - 1);
            if(ans) printf("B\n");
            else printf("G\n");
        }
        else if(op == 1) {
            if(n % 2 == 0 || m % 2 == 0)
                printf("B\n");
            else
                printf("G\n");
        }
    }
    return 0;
}

J
题意:一个船想从(0, a)到(0, 0),要求船的速度v1始终对着(0, 0)问你需要多少时间到达。
思路:直接列方程求解。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const int MAXM = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int main()
{
    int a, v1, v2;
    while(scanf("%d%d%d", &a, &v1, &v2) != EOF) {
        if(a == 0) {
            printf("0\n");
            continue;
        }
        if(v1 < v2 || (v1 == v2 && a != 0)) {
            printf("Infinity\n");
            continue;
        }
        printf("%.10lf\n", a * 1.0 * v1 / (v1 * v1 - v2 * v2));
    }
    return 0;
}

K
题意:问你是否存在两个不同点对使得它们的曼哈顿距离相等。
思路:发现只有2* 1e5 个值,那么循环次数最多也就2 * 1e5次,直接暴力即可。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
const int MAXN = 2 * 1e5 + 10;
const int MAXM = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int x[MAXN], y[MAXN];
bool vis[MAXN];
int main()
{
    int t; scanf("%d", &t);
    while(t--) {
        int n, m; scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++) {
            scanf("%d%d", &x[i], &y[i]);
        }
        CLR(vis, false);
        bool flag = false;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                if(vis[abs(x[i] - x[j]) + abs(y[i] - y[j])]) {
                    flag = true; break;
                }
                vis[abs(x[i] - x[j]) + abs(y[i] - y[j])] = true;
            }
            if(flag) break;
        }
        printf(flag ? "YES\n" : "NO\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值