东华大学2020年程序设计竞赛题解

东华大学2020年程序设计竞赛

题目链接:https://ac.nowcoder.com/acm/contest/5891

A

描述

One day, Li Lei and Han Meimei want to hold a shooting game.
Competition rules:
1.There are three kinds of targets. Red : one point, White : two points, Black : three points.
2.The winner is the first in the competition.
Now Li Lei and Han Meimei are not good at mathematic, so they need your help.

输入格式

First,you will be given a number N,represents the number of competitors.
Given a list about competititor’s ID(form 1 to N), the number of red targets, White targets and Black targets.
The number of competitiors will not exceed 100.

输出格式

You need output the winner’s ID and total points. If there are more than one winners, please output the winner with the smallest ID.

输入样例

5
1 8 3 7
2 6 2 4
3 6 5 0
4 2 6 3
5 1 6 8

输出样例

5 37

题意

有三种颜色的标靶,每个标靶对应不同的分数,输出得分最多人的序号

题解

签到题,直接模拟即可

代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll maxn = 2e6 + 7;
int a[maxn][10];

int main() {
    ll n;
    cin >> n;
    ll id, r, w, b;
    ll sum = 1;
    ll maxid, maxsum = -1;
    while (n--) {
        cin >> id >> r >> w >> b;
        sum = r + 2 * w + 3 * b;
        if (sum > maxsum) {
            maxsum = sum;
            maxid = id;
        }

    }
    cout << maxid << " " << maxsum;

    return 0;
}

B

描述

Given a positive integer y and a prime p, you are asked to find an integer x such that ( x × y ) m o d p = 1 (x×y) mod p=1 (x×y)modp=1. If such x exists, output any x mod p. Otherwise, output -1.

Hint: For any integer a and positive integer b, a mod b is the remainder of a dividing b. Remind that a mod b is non-negative!

输入格式

The first line of input contains a positive integer T, which is the number of test cases. ( 1 ≤ T ≤ 200 , 000 ) (1≤T≤200,000) (1T200,000)
For each test case, there will be one line containing 2 positive integers y, p. ( 1 ≤ y , p ≤ 1 0 9 ) ( 1 \le y, p \le 10^9 ) (1y,p109), p is guaranteed to be a prime)

输出格式

Output one integer for each test case. If such x exists, output any x mod p. Otherwise, output -1.

输入样例

3
1 97
2 97
3 97

输出样例

3
1 97
2 97
3 97

题意

给定y,p 求 x × y m o d p x×ymodp x×ymodp的x的任意解

题解

扩展欧几里得求逆元的模板题

代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll maxn = 2e6 + 7;

void extend_gcd(ll a, ll b, ll &x, ll &y) {
    if (b == 0) {
        x = 1, y = 0;
        return;
    }
    extend_gcd(b, a % b, x, y);
    ll tmp = x;
    x = y;
    y = tmp - (a / b) * y;
}

ll mod_inverse(ll a, ll p) {
    ll x, y;
    extend_gcd(a, p, x, y);
    return (p + x % p) % p;
}

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

int main() {
    ll x, y, p, t, n;
    cin >> t;
    while (t--) {
        x = -1;
        cin >> y >> p;
        if (gcd(y, p) == 1) {
            x = mod_inverse(y, p);
        }
        cout << x << endl;
    }


    return 0;
}

C

描述

YZ is the king of the kingdom. There are n cities in his kingdom. To celebrate the 50th anniversary of the founding of his country, YZ decided to distribute supplies as a reward to all the cities.
We all know that the further the city is from the capital (always at 1), the more it will cost to transport. We define K as the shortest distance between a city and the capital, and ignore the difference in distance between different cities(all is 1 unit). Cost from capital to the city is 2 K 2^K 2K.
Now YZ gives you the map of his kingdom, and asks you if you can calculate the total cost.
(We guarantee that it is a connected graph.)

输入格式

The first line contains two integers n and m ( 1 ≤ n ≤ 1 0 6 , n − 1 ≤ m ≤ m i n ( 2 ∗ 1 0 6 , ( n − 1 ) ∗ n / 2 ) ) (1 \le n \le 10^6,n-1 \le m \le min(2*10^6,(n-1)*n/2)) (1n106,n1mmin(2106,(n1)n/2)), which means there are n cities and m roads.
The next m lines contains two integers u and v, denoting there is a road connecting city u and city v.

输出格式

Print the only line containing a single integer. It should be equal to the total cost mod 1e9+7.

输入样例

3 2
1 2
2 3

输出样例

6

题意

给一个n个节点m条边的无向图,边权都是1,初始点到任意距离为K的点的费用是 2 K 2^K 2K,求总费用。

题解

dijkstra

代码

#include <bits/stdc++.h>

using namespace std;
const int maxn = 2e6 + 10, mod = 1e9 + 7;
#define Head head
int n, m, dis[maxn];
typedef unsigned long long ull;
typedef long long ll;
struct node {
    int to, w, next;
} edge[maxn << 2];
int head[maxn], tot;

void init() {
    memset(head, -1, sizeof(head));
    memset(dis, 0x3f3f3f3f, sizeof(dis));
    tot = 0;
}

void addEdge(int u, int v, int w) {
    edge[tot].to = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

struct cmp {
    //优先队列的排序函数;
    bool operator()(int &a, int &b) const {
        return dis[a] > dis[b];
    }
};

void dijkstra(int Dis[], int x) {
    //用优先队列寻找Dis[]最小点;
    //代替遍历搜索,节约时间;
    priority_queue<int, vector<int>, cmp> q;
    Dis[x] = 0;
    q.push(x);                       //将x 加入队列,涂成灰色;
    while (!q.empty()) {
        int u = q.top();
        q.pop();                     //将x 出队列,涂成白色;
        for (int k = Head[u]; k != -1; k = edge[k].next) {
            int v = edge[k].to;
            if (Dis[v] > Dis[u] + edge[k].w) {
                Dis[v] = Dis[u] + edge[k].w;
                q.push(v);           //将x+ 1加入队列,涂成灰色;
            }
        }
    }
}

int read() {
    int x = 0, w = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {  // ch 不是数字时
        if (ch == '-') w = -1;        // 判断是否为负
        ch = getchar();               // 继续读入
    }
    while (ch >= '0' && ch <= '9') {  // ch 是数字时
        x = x * 10 + (ch - '0');  // 将新读入的数字’加’在 x 的后面
        // x 是 int 类型,char 类型的 ch 和 ’0’ 会被自动转为其对应的
        // ASCII 码,相当于将 ch 转化为对应数字
        // 此处也可以使用 (x<<3)+(x<<1) 的写法来代替 x*10
        ch = getchar();  // 继续读入
    }
    return x * w;  // 数字 * 正负号 = 实际数值
}

ull binpow(ull x, ull z, ull p) {
    x %= p;
    z %= p;
    ull prod = 1;
    while (z > 0) {
        if (z & 1) prod = prod * x % p;//判断指数二进制最后一位是不是1,也相当于z%2==1;
        (x *= x) %= p;
        z >>= 1;//z右移一位
    }
    return prod;
}

ll qpow(ll a, ll b) {
    ll ans = 1;
    a %= mod;
    assert(b >= 0);
    for (; b; b >>= 1) {
        if (b & 1)ans = ans * a % mod;
        a = a * a % mod;
    }
    return ans;
}

int main() {
    //dijkstra+链式前向星
    n = read();
    m = read();
    //n个顶点 m条边
    init();
    for (int i = 0; i < m; i++) {
        int u, v;
        u = read();
        v = read();
        addEdge(u, v, 1);
        addEdge(v, u, 1);
    }
    dijkstra(dis, 1);
    long long ans = 0;
    for (int i = 2; i <= n; i++) {
        int k = dis[i];
        ans = (ans % mod + binpow(2, k, mod)) % mod;//2^k%mod
    }
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值