A_数字方阵

牛客小白月赛2 题解_c代码

思路
假如 我们按照

1 2 3
4 5 6
7 8 9

就会发现 每一行 每一列 都不一样 但是 两条对角线上的元素是一样的

这样的话

1 2 7
3 4 8
5 6 9

我将前两列按照 这样的顺序 排 然后最后一排改一下 就可以了。

其实不一定是这样 还是有很多其它排列的方法的

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

int G[maxn][maxn];

int main()
{
    int n;
    scanf("%d", &n);
    int pos = 1;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n - 1; j++)
            G[i][j] = pos++;
    for (int i = 0; i < n; i++)
        G[i][n - 1] = pos++;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            printf("%d%c", G[i][j], (j == n - 1) ? '\n' : ' ');
}

B_小马过河

牛客小白月赛2 题解_#define_02

牛客小白月赛2 题解_c代码_03

思路

其实问题就是 给出一个点P 给出一条线 L 找出一条线 L’ 使得 L’ 经过点P 并且垂直于线L 然后求出 两线交点就可以

假如线L 的一般式为 Ax+By+c = 0
那么垂直于线L的直线束就是 Bx - Ay + m = 0
那么把点P 代入直线束 就可以求出参数m 也就得到 两条线了 再求交就可以

那么问题来了
给出两点 怎么求一条线L的一般式呢

参考博客

javascript:void(0)

A=Y2-Y1
B=X1-X2
C=X2*Y1-X1*Y2

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        double px, py, ux, uy, vx, vy;
        scanf("%lf%lf%lf%lf%lf%lf", &px, &py, &ux, &uy, &vx, &vy);
        double A = vy - uy;
        double B = ux - vx;
        double C = vx * uy - ux * vy;
        double m = A * py - B * px;
        double y = (A * m - B * C) / (A * A + B * B);
        double x = (A * y - m) / B;
        printf("%.7lf %.7lf\n", x, y);
    }
}

C_真真假假

牛客小白月赛2 题解_#define_04

牛客小白月赛2 题解_#define_05

思路
这个其实很简单 ,把所有头文件用map 标记一下 然后每次输入 都查找一下是否存在就可以了

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 20 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

map <string, int> m;

void init()
{
    m["algorithm"] = 1;
    m["bitset"] = 1;
    m["cctype"] = 1;
    m["cerrno"] = 1;
    m["clocale"] = 1;
    m["cmath"] = 1;
    m["complex"] = 1;
    m["cstdio"] = 1;
    m["cstdlib"] = 1;
    m["cstring"] = 1;
    m["ctime"] = 1;
    m["deque"] = 1;
    m["exception"] = 1;
    m["fstream"] = 1;
    m["functional"] = 1;
    m["limits"] = 1;
    m["list"] = 1;
    m["map"] = 1;
    m["iomanip"] = 1;
    m["ios"] = 1;
    m["iosfwd"] = 1;
    m["iostream"] = 1;
    m["istream"] = 1;
    m["ostream"] = 1;
    m["queue"] = 1;
    m["set"] = 1;
    m["sstream"] = 1;
    m["stack"] = 1;
    m["stdexcept"] = 1;
    m["streambuf"] = 1;
    m["string"] = 1;
    m["utility"] = 1;
    m["vector"] = 1;
    m["cwchar"] = 1;
    m["cwctype"] = 1;
}

int main()
{
    init();
    int t;
    cin >> t;
    while (t--)
    {
        string s;
        cin >> s;
        puts(m[s]?"Qian":"Kun");
    }
}

D_虚虚实实

牛客小白月赛2 题解_c代码_06

牛客小白月赛2 题解_#define_07

思路
这个其实就是判断一下给的无向图是不是欧拉通路
只需要判断一下 点的度数为奇数的个数 是否等于0 或者 等于2 是的话 就是欧拉通路 不是的话 就不是
这个给出的图不一定是连通的

所以首先要判断一下图的连通性 如果图不连通 那肯定不是欧拉通路

用 DFS BFS 判断都可以

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
//#define bug puts("***bug***");
#define bug
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 2e2 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       


int du[maxn];

int visit[maxn];

int G[maxn][maxn];

int flag;

int n, m;

void bfs()
{
    queue <int> q;
    q.push(1);
    visit[1] = 1;
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i = 1; i <= n; i++)
        {
            if (visit[i] == 0 && G[u][i] == 1)
            {
                visit[i] = 1;
                flag++;
                q.push(i);
            }
        }
    }
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
            du[i] = 0, visit[i] = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                G[i][j] = G[j][i] = 0;
        int x, y;
        for (int i = 0; i < m; i++)
        {
            scanf("%d%d", &x, &y);
            G[x][y] = G[y][x] = 1;
            du[x]++, du[y]++;
        }
        int tot = 0;
        flag = 1;
        bfs();
        for (int i = 1; i <= n; i++)
            tot += (du[i] & 1);
        if ((tot == 0 || tot == 2) && flag == n)
            puts("Zhen");
        else
            puts("Xun");
    }
}

E_是是非非

牛客小白月赛2 题解_i++_08

牛客小白月赛2 题解_c代码_09

思路
题目其实是Nim博弈的变形

我们知道 Nim 博弈的 判断方法 是将每堆石子的数量异或起来 如果最后异或值为0 那么先手的人就没有必胜策略 反之则有

这题中的意思是 每次更改其中一堆 然后再判断
如果每次更改一堆后 再重新异或判断 会T
那么怎么办呢
其实异或是有消去律的

也就是说 异或自己两次 就 相当于没有异或

所以 我们可以再输入过程中 先把所有的值都异或一遍
这样 我们就可以 在每次更改的基础上 先异或没有更改的那个值 来消去
再去更改那个值 再去异或 更改后的值 那么就是我们要的最终的异或值了

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define bug 
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

int arr[maxn];

int main()
{
    int n, q;
    scanf("%d%d", &n, &q);
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &arr[i]);
        ans ^= arr[i];
    }
    int x, y;
    while (q--)
    {
        scanf("%d%d", &x, &y);
        ans ^= arr[x];
        arr[x] = y;
        ans ^= arr[x];
        puts(ans ? "Kan" : "Li");
    }
}

F_黑黑白白

牛客小白月赛2 题解_ios_10

牛客小白月赛2 题解_c代码_11

思路

对于这个问题,我们可以一层一层的看

比如题目给出的样例当中

牛客小白月赛2 题解_#include_12

除了根节点

显然 偶数层 就是先手的人的选择
那么 奇数层 便是后手的人的选择

从奇数层下来 会有两条路 这时候 是先手的人选择 如果这个时候 有一条路是叶子节点了 那么先手的人就是可以胜利的
这个时候 就返回答案就可以了 不用再往下搜了

那么什么时候 是后手的人可以获胜的情况呢

就是 偶数层下来 两个方向 后手的人在其中一个方向可以获得胜利,那么先手的人是没有必胜策略的

比如下面这种情况
牛客小白月赛2 题解_#define_13

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
//#define bug 
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

vector <int> edge[maxn];

int n, r;

bool dfs(int root, int pre)
{
    int len = edge[root].size();
    if (len == 0) return false;
    for (int i = 0; i < len; i++)
    {
        int v = edge[root][i];
        if (v == pre) continue;
        if (dfs(v, root) == false) return true;
    }
    return false;
}

void clear()
{
    for (int i = 1; i <= n; i++)
        edge[i].clear();
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        clear();
        scanf("%d%d", &n, &r);
        int len = n - 1;
        int x, y;
        for (int i = 0; i < len; i++)
        {
            scanf("%d%d", &x, &y);
            edge[x].pb(y);
            edge[y].pb(x);
        }
        puts(dfs(r, -1) ? "Gen" : "Dui");
    }
}

G_文

牛客小白月赛2 题解_#include_14

牛客小白月赛2 题解_#include_15

思路
这个保存一下正确答案 然后将选手的答案 一个一个去比对就可以了

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 20 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    string sta;
    cin >> sta;
    string ans = "zzzzzzzzzzzzzzzzz", tmp, tmm;
    int Max = -INF;
    for (int i = 0; i < m; i++)
    {
        int tot = 0;
        cin >> tmp >> tmm;
        for (int j = 0; j < n; j++)
            if (tmm[j] == sta[j])
                tot++;
        if (tot > Max || (tot == Max && tmp < ans))
        {
            Max = tot;
            ans = tmp;
        }
    }
    cout << ans << endl;
    printf("%.2lf\n", Max * 1.0 / n * 100.0);
}

H_武

牛客小白月赛2 题解_#include_16

牛客小白月赛2 题解_i++_17

思路

跑一下 Djikstra 然后 将dist 排序 输出第K个就可以了

但是要注意 因为N比较大 所以要存边 然后用优先队列优化 就能过

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
//#define bug 
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

struct node
{
    int v, c;
    node(int _v = 0, int _c = 0) : v(_v), c(_c) {}
    bool operator < (const node &r) const
    {
        return c > r.c;
    }
};

struct Edge
{
    int v, cost;
    Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost){}
};

vector <Edge> E[maxn];
bool vis[maxn];
int dist[maxn];

void dijkstra(int n, int start)
{
    CLR(vis, false);
    for (int i = 1; i <= n; i++) dist[i] = INF;
    priority_queue <node> que;
    while (!que.empty()) que.pop();
    dist[start] = 0;
    que.push(node(start, 0));
    node tmp;
    while (!que.empty())
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if (vis[u]) continue;
        vis[u] = true;
        int len = E[u].size();
        for (int i = 0; i < len; i++)
        {
            int v = E[tmp.v][i].v;
            int cost = E[u][i].cost;
            if (!vis[v] && dist[v] > dist[u] + cost)
            {
                dist[v] = dist[u] + cost;
                que.push(node(v, dist[v]));
            }
        }
    }
}

void addedge(int u, int v, int w)
{
    E[u].pb(Edge(v, w));
}

int main()
{
    int n, p, k;
    scanf("%d%d%d", &n, &p, &k);
    int len = n - 1;
    int u, v, w;
    while (len--)
    {
        scanf("%d%d%d", &u, &v, &w);
        addedge(u, v, w);
        addedge(v, u, w);
    }
    dijkstra(n, p);
    sort(dist + 1, dist + 1 + n);
    printf("%d\n", dist[k + 1]);
}

I_艺
牛客小白月赛2 题解_c代码_18

牛客小白月赛2 题解_#include_19

思路
这个只需要判断一下 每分钟哪个节目的愉悦度高 就看哪个就好了 For 几遍 复杂度O(n)
但是要注意 如果两个愉悦度都是负的 那么可以选择这时刻不看 也就是 愉悦度为0

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define bug 
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

struct node
{
    int s, e, v;
    node() {}
    node(int _s, int _e, int _v) : s(_s), e(_e), v(_v) {}
    bool operator < (const node& r) const
    {
        return s < r.s;
    }
    void read()
    {
        scanf("%d%d", &s, &v);
    }
}a[maxn], b[maxn];


int main()
{
    int n, m, t;
    scanf("%d%d%d", &n, &m, &t);
    for (int i = 0; i < n; i++)
        a[i].read();
    for (int i = 0; i < m; i++)
        b[i].read();
    sort(a, a + n);
    sort(b, b + m);
    a[n].s = b[m].s = t;
    for (int i = 0; i < n; i++)
        a[i].e = a[i + 1].s;
    for (int i = 0; i < m; i++)
        b[i].e = b[i + 1].s;
    ll ans = 0;
    for (int i = 1, j = 0, k = 0; i <= t; i++)
    {
        if (a[j].e < i) j++;
        if (b[k].e < i) k++;
        ans += max(a[j].v, max(b[k].v, 0));
    }
    cout << ans << endl;
}

J_美

牛客小白月赛2 题解_#include_20

牛客小白月赛2 题解_i++_21

思路

这个就是尽量让相邻的两个人帅气值尽量差距大就可以了
那么显然 先排序

先放一个最小的 再放一个最大的 这样放下去。。

比如 样例中
5
7 3 15 12 8

排序后就是

3 8 7 12 15

按照那种排放方式 排放下来就是

3 15 7 12 8

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>

#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
//#define bug puts("***bug***");
#define bug
//#define gets gets_s

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;

const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

int a[maxn], b[maxn];

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    sort(a, a + n);
    for (int i = 0, j = n - 1, pos = 0; pos < n; i++, j--)
    {
        b[pos++] = a[i];
        if (pos < n)
            b[pos++] = a[j];
    }
    ll ans = 0;
    for (int i = 1; i < n; i++)
        ans += abs(b[i] - b[i - 1]);
    ans += b[n - 1] - b[0];
    printf("%lld\n", ans);

}