牛客小白月賽2 題解

A_數字方陣

這裏寫圖片描述

思路
假如 我們按照

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_小馬過河

這裏寫圖片描述

這裏寫圖片描述

思路

其實問題就是 給出一個點P 給出一條線 L 找出一條線 L’ 使得 L’ 經過點P 並且垂直於線L 然後求出 兩線交點就可以

假如線L 的一般式爲 Ax+By+c = 0
那麼垂直於線L的直線束就是 Bx - Ay + m = 0
那麼把點P 代入直線束 就可以求出參數m 也就得到 兩條線了 再求交就可以

那麼問題來了
給出兩點 怎麼求一條線L的一般式呢

參考博客

http://www.cnblogs.com/DHUtoBUAA/p/8057056.html

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_真真假假

這裏寫圖片描述

這裏寫圖片描述

思路
這個其實很簡單 ,把所有頭文件用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_虛虛實實

這裏寫圖片描述

這裏寫圖片描述

思路
這個其實就是判斷一下給的無向圖是不是歐拉通路
只需要判斷一下 點的度數爲奇數的個數 是否等於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_是是非非

這裏寫圖片描述

這裏寫圖片描述

思路
題目其實是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_黑黑白白

這裏寫圖片描述

這裏寫圖片描述

思路

對於這個問題,我們可以一層一層的看

比如題目給出的樣例當中

這裏寫圖片描述

除了根節點

顯然 偶數層 就是先手的人的選擇
那麼 奇數層 便是後手的人的選擇

從奇數層下來 會有兩條路 這時候 是先手的人選擇 如果這個時候 有一條路是葉子節點了 那麼先手的人就是可以勝利的
這個時候 就返回答案就可以了 不用再往下搜了

那麼什麼時候 是後手的人可以獲勝的情況呢

就是 偶數層下來 兩個方向 後手的人在其中一個方向可以獲得勝利,那麼先手的人是沒有必勝策略的

比如下面這種情況
這裏寫圖片描述

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_文

這裏寫圖片描述

這裏寫圖片描述

思路
這個保存一下正確答案 然後將選手的答案 一個一個去比對就可以了

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_武

這裏寫圖片描述

這裏寫圖片描述

思路

跑一下 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_藝
這裏寫圖片描述

這裏寫圖片描述

思路
這個只需要判斷一下 每分鐘哪個節目的愉悅度高 就看哪個就好了 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_美

這裏寫圖片描述

這裏寫圖片描述

思路

這個就是儘量讓相鄰的兩個人帥氣值儘量差距大就可以了
那麼顯然 先排序

先放一個最小的 再放一個最大的 這樣放下去。。

比如 樣例中
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);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章