《看了受制了》,第二十二天,5道题,合计103道题

2023年9月20日

Acwing图论加牛客的几道题,今天这个牛客D太帅了这个思路。

牛客周赛 游游的数字圈

题目理解

就统计个数即可,0、6、8、9分别是1、1、2、1

代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f3f;

ll qmi(ll a, ll b){
    ll res = 1;
    while(b)
    {
        if(b & 1) res = res * a % Mod;
        a = a * a % Mod;
        b >>= 1;
    }
    return res;
}

ll inv(ll x){ return qmi(x, Mod - 2);}
ll mo(ll x){ return (x % Mod + Mod) % Mod;}

int a[] = {1, 0, 0, 0, 0, 0, 1, 0, 2, 1};


int main() {

    string s;
    cin >> s;
    int res = 0;
    for(int i = 0; i < s.size(); i++)
        res += a[(int)s[i] - 48];
    
    cout << res;

    return 0;
}

牛客周赛 竖式乘法

题目理解

用A的每一个数字去乘B得到的积求和即可。

代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;

ll qmi(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
            res = res * a % Mod;
        a = a * a % Mod;
        b >>= 1;
    }
    return res;
}

ll inv(ll x) { return qmi(x, Mod - 2); }
ll mo(ll x) { return (x % Mod + Mod) % Mod; }

ll T, a, b;

int main()
{
    cin >> T;

    while(T--)
    {
        cin >> a >> b;

        vector<ll> q;
        while(b)
        {
            q.push_back(a * (b % 10));
            b /= 10;
        }

        ll res = 0;

        for(int i = 0 ; i < q.size(); i++)
            res += q[i];
        
        cout << res << endl;
    } 
    return 0;
}

牛客周赛 游游的数值距离

题目理解

这个x一定是尽可能小,并且大于等于1且不等于2,然后多往后匹配一个y即可。因为阶乘太大了,根本不可能。很大.

  • 切记一定是,大于等于1 且不等于2,认真读题!
  • 可以多匹配一个y

代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;

ll qmi(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
            res = res * a % Mod;
        a = a * a % Mod;
        b >>= 1;
    }
    return res;
}

ll inv(ll x) { return qmi(x, Mod - 2); }
ll mo(ll x) { return (x % Mod + Mod) % Mod; }

ll res = 1e10, x = 1, y = 1;
ll n;
bool check(int mid, ll Q)
{
    if ((Q)*mid - mid >= n)
        return true;

    return false;
}

int main()
{
    cin >> n;
    ll q = 1;
    res = n;
    for (int i = 2; i <= 15; i++)
    {
        q *= i;
        if (i == 2)
            continue;

        ll t = n / (q - 1);

        if(abs(q * t - t - n) < res && t != 2 && t >= 1)
        {
            res = abs(q * t - t - n);
            x = i;
            y = t;
        }
        t++;
        if(abs(q * t - t - n) < res && t != 2 && t >= 1)
        {
            res = abs(q * t - t - n);
            x = i;
            y = t;
        }
    }

    cout << x << " " << y;

    return 0;
}

牛客周赛 游游的k好数组

题目理解

今天这个题,最帅的一集哦!

  • 公式理解:

\[a_0 + a_1 + a_2 + ... + a_{k-1} == a_1 + a_2 + ... + a_{k-1} + a_k \]

我们可以从以上公式推出:\(a_0 == a_k\)。即,第1组的第一个是等于第二组的第一个,那么也就继续可以推导,数组里面所有的数相等。

  • 求出一组k长度的每一个位置的最大值。可以通过以下的滚动数组来求得每一个位置上的最大值。来作为K好数组的最小值。
m[i % k] = min(m[i % k], a[i]);
  • 然后我们得到位置上的最大值,就可以进行与对应的每一个数组进行做差。
  • 如果差是大于x,那么就肯定形不成k好数组
  • 如果x再形成后还有剩余。
  • 那么就可以加一下,加的值是多大呢?
q / (n / k + (n % k > i)); 因为一共要给 n / k + (n % k > i)数组加和

代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

const int Mod = 1e9 + 7, N = 1e5 + 10;
const int INF = 0x3f3f3f3f;

ll qmi(ll a, ll b){
    ll res = 1;
    while(b)
    {
        if(b & 1) res = res * a % Mod;
        a = a * a % Mod;
        b >>= 1;
    }
    return res;
}

ll inv(ll x){ return qmi(x, Mod - 2);}
ll mo(ll x){ return (x % Mod + Mod) % Mod;}

int T;
ll n, k, q;


int main() {

    scanf("%d", &T);

    while(T--)
    {
        scanf("%lld%lld%lld", &n, &k, &q);

        vector<ll> a(n);

        for(int i = 0; i < n; i++)
            cin >> a[i];
        
        vector<ll> m(k);
        // 找到每个位置的最大值
        for(int i = 0; i < n; i++)
            m[i % k] = max(m[i % k], a[i]);
        
        ll cnt = 0;
        for(int i = 0; i < n; i++)
            cnt += m[i % k] - a[i];
        
        if(cnt > q)
        {
            printf("-1\n");
            continue;
        }
        
        ll res = 0;
        q -= cnt;

        for(int i = 0; i < k; i++)
        {
            int c = n / k + (n % k > i);
            res = max(res, m[i] + q / c);
        }
        
        printf("%d\n", res);
    }

    return 0;
}

Acwing1128 信使

题目理解

仔细读题!仔细读题!
它会同时往所有的联通路进行走,那么到每个点都是相同的出发点,相同的出发时刻。
所以答案就是!!!最远的点!!!
图论的题一定要好好理解题意。

代码实现

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

const int Mod = 1e9 + 7, N = 110;
const int INF = 0x3f3f3f3f;

ll qmi(ll a, ll b){
    ll res = 1;
    while(b)
    {
        if(b & 1) res = res * a % Mod;
        a = a * a % Mod;
        b >>= 1;
    }
    return res;
}

ll inv(ll x){ return qmi(x, Mod - 2);}
ll mo(ll x){ return (x % Mod + Mod) % Mod;}

int d[N], g[N][N], dist[N][N];
int n, m;
bool st[N];
bool flag[N];
int dijkstra()
{
    memset(d, INF, sizeof d);
    memset(st, 0, sizeof st);
    d[1] = 0;

    for(int i = 1; i <= n; i++)
    {
        int t = -1;

        for(int j = 1; j <= n; j++)
            if(!st[j] && (t == -1 || d[j] < d[t]))
                t = j;

        st[t] = true;

        for(int j = 1; j <= n; j++)
            d[j] = min(d[j], d[t] + g[t][j]);
    }
    
    int res = 0;
    for(int i = 1; i <= n; i++)
        if(d[i] > INF / 2)
            return -1;
        else
            res = max(res, d[i]);
    
    return res;
}

int main() {

    memset(g, INF, sizeof g);
    memset(dist, INF, sizeof dist);
    scanf("%d%d", &n, &m);

    while(m -- )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);

        g[a][b] = min(g[a][b], c);
        g[b][a] = min(g[b][a], c);

    }

    cout << dijkstra();

    return 0;
}
posted @ 2023-09-21 00:52  wxzcch  阅读(12)  评论(0)    收藏  举报