The 2021 Sichuan Provincial Collegiate Programming Contest

A - Chuanpai

思路:

可以打表,但不如枚举快,枚举就从1到6两重循环,由于1,3  3,1算一种,所以第二重直接从i开始就可以

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>

#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010, MOD = 1000000007, INF = 0x3f3f3f3f;

int main()
{
    IOS;
    int T;
    cin >> T;
    while(T -- )
    {
        int k;
        cin >> k;
        int res = 0;
        for (int i = 1; i <= 6; i ++ )
            for (int j = i; j <= 6; j ++ )
                if(i + j == k)
                    res++;

        cout << res << endl;
    }
    return 0;
}

B - Hotpot

思路:

由于m太大所以必然不能遍历m次操作,我们可以把2n次操作算作一轮,然后可以把这m次操作分成若干轮,找找有多少次这样的2n轮,最后凑不成一轮的多出来的几次操作单独遍历处理就可以了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>

#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010, MOD = 1000000007, INF = 0x3f3f3f3f;

PII pot[N];
bool st[N];

int main()
{
    IOS;
    int T;
    cin >> T;
    while(T -- )
    {
        int n, k, m;
        cin >> n >> k >> m;
        memset(st, 0, sizeof st);
        for (int i = 0; i < n; i ++ )
        {
            cin >> pot[i].first;
            pot[i].second = 0;
        }
        for (int i = 0; i < 2 * n; i ++ )
        {
            int idx = i % n;
            if(st[pot[idx].first])
            {
                st[pot[idx].first] = 0;
                pot[idx].second++;
            }
            else
                st[pot[idx].first] = 1;
        }

        int tmp = m / (2 * n);//m中有多少个2n
        for (int i = 0; i < n; i ++ )
            pot[i].second *= tmp;

        int mod = m % (2 * n);//多出来的几个单独处理
        for (int i = 0; i < mod; i ++ )
        {
            int idx = i % n;
            if (st[pot[idx].first])
            {
                st[pot[idx].first] = 0;
                pot[idx].second++;
            }
            else
                st[pot[idx].first] = 1;
        }
        for (int i = 0; i < n - 1; i ++ )
            cout << pot[i].second << ' ';
        cout << pot[n - 1].second << endl;
    }
    return 0;
}

D - Rock Paper Scissors

思路:

先手的所有出牌情况都不会影响结果,只能是后手才会影响,而后手会优先考虑赢的情况,然后是平局,最后才是输的情况,所以依次判断先手石头剪刀布的后手情况即可,记得开long long

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>

#define int LL
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010, MOD = 1000000007, INF = 0x3f3f3f3f;

PII pot[N];
bool st[N];

signed main()
{
    IOS;
    int T;
    cin >> T;
    while(T -- )
    {
        int br, bp, bs, dr, dp, ds;
        cin >> br >> bp >> bs >> dr >> dp >> ds;
        int res = 0;
        if(br)
        {
            if(dp && br)//
            {
                int tmp = min(dp, br);
                res += tmp;
                dp -= tmp;
                br -= tmp;
            }
            if(dr && br)//
            {
                int tmp = min(dr, br);
                dr -= tmp;
                br -= tmp;
            }
            if(ds && br)//
            {
                int tmp = min(ds, br);
                res -= tmp;
                ds -= tmp;
                br -= tmp;
            }
        }
        if (bp)
        {
            if (ds && bp) //
            {
                int tmp = min(ds, bp);
                res += tmp;
                ds -= tmp;
                bp -= tmp;
            }
            if (dp && bp) //
            {
                int tmp = min(dp, bp);
                dp -= tmp;
                bp -= tmp;
            }
            if (dr && bp) //
            {
                int tmp = min(dr, bp);
                res -= tmp;
                ds -= tmp;
                br -= tmp;
            }
        }
        if (bs)
        {
            if (dr && bs) //
            {
                int tmp = min(dr, bs);
                res += tmp;
                dr -= tmp;
                bs -= tmp;
            }
            if (ds && bs) //
            {
                int tmp = min(ds, bs);
                ds -= tmp;
                bs -= tmp;
            }
            if (dp && bs) //
            {
                int tmp = min(dp, bs);
                res -= tmp;
                dp -= tmp;
                bs -= tmp;
            }
        }
        cout << res << endl;
    }
    return 0;
}

E - Don't Really Like How The Story Ends

思路:

题解

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>

#define int LL
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010, MOD = 1000000007, INF = 0x3f3f3f3f;

int n, m;
int nxt, res;
vector<int> g[N];

//u表示当前点序号,nxt表示下一个要到的点的序号
void dfs(int u)
{
    if(u == n + 1)
        return;

    for (auto x : g[u])
    {
        if(x < nxt)
            continue;

        while(x >= nxt)
        {
            if(x == nxt)
                nxt++, dfs(nxt - 1);//nxt指向下一个要到的点,nxt-1表示上次的nxt变成了现在的点,并dfs这个点
            else if(x > nxt)
                res++, nxt++, dfs(nxt - 1);
        }
    }
}

signed main()
{
    IOS;
    int T;
    cin >> T;
    while(T -- )
    {
        for (int i = 1; i <= n; i ++ )
            g[i].clear();

        cin >> n >> m;
        while(m -- )
        {
            int a, b;
            cin >> a >> b;
            g[a].push_back(b), g[b].push_back(a);
        }
        g[1].push_back(n + 1);//为了方便让1和n+1相连
        for (int i = 1; i <= n; i ++ )
            sort(g[i].begin(), g[i].end());

        nxt = 2, res = 0;
        dfs(1);

        cout << res << endl;
    }
    return 0;
}

 

L - Spicy Restaurant

 思路:

这题有点东西,这题是用w值来bfs,有点类似反推,就好比本来要从1号结点走到3号结点,那么现在的过程就转化成了从3号结点开始宽搜反着搜到1号结点,那么我们最多bfs100次即可得出所有的情况

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>

#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 110, M = 100010, MOD = 1000000007, INF = 0x3f3f3f3f;

int n, m, q;
int e[2 * M], ne[2 * M], h[M], idx;
int w[M];
int dist[M][N]; //dist[i][j]表示距离i最近的属性值恰好为j的点的距离
bool st[M];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void bfs(int v)
{
    memset(st, 0, sizeof st);
    queue<int> q;
    for (int i = 1; i <= n; i++)
        if (w[i] == v)
        {
            q.push(i);
            st[i] = true;
            dist[i][v] = 0;
        }

    while (!q.empty())
    {
        auto t = q.front();
        q.pop();

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (st[j])
                continue;

            st[j] = true;
            dist[j][v] = dist[t][v] + 1;
            q.push(j);
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    memset(h, -1, sizeof h);
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++)
        cin >> w[i];

    while (m--)
    {
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }

    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= 100; j ++ )
            dist[i][j] = INF; //注意dist的初始化不能在bfs里面,且memset会超时

        for (int i = 1; i <= 100; i++)
            bfs(i);

    while (q--)
    {
        int cur, v;
        cin >> cur >> v;
        int res = INF;
        for (int i = 1; i <= v; i++)
            res = min(res, dist[cur][i]);

        if (res == INF)
            cout << -1 << endl;
        else
            cout << res << endl;
    }

    return 0;
}

 

posted @ 2021-10-16 22:33  彦辰kkkkk  阅读(148)  评论(0)    收藏  举报