Codeforces Round 871 (Div. 4)

  • Post author:
  • Post category:其他





传送门



A. Love Story

 signed main()
{
    IO;
    int t;cin >> t;
    string ss = "codeforces";
    while(t--)
    {
        string s;cin >> s;
        int cnt = 0;
        for(int i = 0;i < 10;i ++)
        {
            if(s[i] != ss[i])
                cnt ++;
        }
        cout << cnt << endl;
    }
    return 0;
}    



B. Blank Space

signed main()
{
    IO;
    int t; cin >> t;
    while (t--)
    {
        int n; cin >> n;
        vector<int> a(n);
        int ans = 0, cnt = 0;
        for (int i = 0; i < n; i++)
        {
            cin >> a[i];
            if (a[i] != 0) {
                ans = max(ans, cnt);
                cnt = 0;
            }
            else
                cnt++;
        }
        ans = max(ans, cnt);
        cout << ans << endl;
    }
    return 0;
}



C. Mr. Perfectly Fine

题意:有



n

n






n





本书,每本书可以使你学会



a

a






a





技能或



b

b






b





技能,或者同时学会



a

b

a, b






a





b





技能。看每本书都有对应的代价,求学会两种技能的最小代价

思路:将书分为只学会



a

a






a





技能和只学会



b

b






b





技能和同时学会



a

b

ab






ab





技能,三种类型,用



3

3






3





个变量维护三种类型各自的最小代价,最后得到答案。

signed main()
{
    IO;
    int t; cin >> t;
    
    while (t--)
    {
        int n;cin >> n;
        int cnt1 = oo, cnt2 = oo, cnt3 = oo;
        for(int i = 1;i <= n;i ++)
        {
            int ti;cin >> ti;
            string k;cin >> k;
            if(k[0] == '1' && k[1] != '1')
                cnt2 = min(cnt2, ti);
            if(k[0] == '1' && k[1] == '1')
                cnt1 = min(cnt1, ti);
            if(k[0] != '1' && k[1] == '1')
                cnt3 = min(cnt3, ti);
        }
        int ans = min(cnt1, cnt2 + cnt3);
        if(ans >= oo)
            cout << -1 << endl;
        else
            cout << ans << endl;
    }
    return 0;
}



D. Gold Rush

题意:有一堆



n

n






n





个金币,没次操作可以将其分为



a

,

b

a,b






a


,




b





两堆,但是二者数量的比值必须为



2

:

1

2:1






2




:








1





,问能否通过一系列操作得到个数为



m

m






m





的堆

思路:





n

(

1

3

)

p

(

2

3

)

q

=

m

n * (\frac{1}{3})^p * (\frac{2}{3})^q = m






n













(













3














1





















)










p




















(













3














2





















)










q











=








m







显然





m

n

=

2

q

3

p

+

q

\frac{m}{n}=\frac{2 ^q}{3^{p+q}}

















n














m






















=




















3











p


+


q























2










q
































所以通分



m

/

n

m/n






m


/


n





,然后分解



m

n

m,n






m





n





的因子,如果



m

m






m





只包含因子



2

2






2









n

n






n





只包含因子



3

3






3





,且3的个数大于2的个数就有解

 signed main()
{
    IO;
    int t; cin >> t;
 
    while (t--)
    {
        int n, m;
        cin >> n >> m;
        int d = gcd(m, n);
        int cnt2 = 0, cnt3 = 0;
        m /= d, n /= d;
        // cout << n << ' ' << m << endl;
        while (m % 2 == 0)m /= 2, cnt2++;
        while (n % 3 == 0)n /= 3, cnt3++;
        if (m == 1 && m == n && cnt3 >= cnt2)
            cout << "YES\n";
        else
            cout << "NO\n";
    }
    return 0;
}



E. The Lakes

纯bfs没什么其他的

#include <bits/stdc++.h>
#define oo 0x3f3f3f3f
#define ll long long
#define OO 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(false);cin.tie(nullptr)
#define endl "\n"
#define int ll
const int N = 2e5 + 10, M = 2 * N;
using namespace std;
typedef pair<int, int> pii;
#define deb(i,x) if(int i==x) int k = 1; 
#define all(x) x.begin(),x.end()
ll lowbit(ll x) { return x & -x; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qmi(ll a, ll b, ll mod) {
    ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; }
    return res;
}
int g[1001][1001];
int vis[1001][1001];
int n, m;
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
int bfs(int x, int y)
{
    int ans = 0;
    queue<array<int, 2>> q;
    q.push({x, y}), vis[x][y] = 1;
    while(q.size())
    {
        auto t = q.front(); q.pop();
        int x = t[0], y = t[1];
        ans += g[x][y];
        for(int i = 0;i < 4;i ++)
        {
            int xx = x + dx[i], yy = y + dy[i];
            if(xx > n || xx < 1 || yy > m || yy < 1)continue;
            if(vis[xx][yy]) continue;
            if(g[xx][yy] > 0)
            {
                vis[xx][yy] = 1;
                q.push({xx, yy});
            }
        }
    }
    return ans;
}
signed main()
{
    IO;
    int t; cin >> t;

    while (t--)
    {
        cin >> n >> m;
        for(int i = 1;i <= n;i ++)
            for(int j = 1;j <= m;j ++)
                cin >> g[i][j], vis[i][j] = 0;
        int ans = 0;
        for(int i = 1;i <= n;i ++)
            for(int j = 1;j <= m;j ++)
            {
                if(!vis[i][j] && g[i][j] > 0)
                    ans = max(ans, bfs(i, j));
            }
        cout << ans << endl;
    }
    return 0;
}



F. Forever Winter

题意:有一个图,其根节点直接与



x

x






x





个节点相邻,而这



x

x






x





个节点每一个又都和



y

y






y





个节点相邻。给定图中的点数和边数和所有边。求



x

,

y

x,y






x


,




y




思路:先求出图的最长直经,找到直径的两个端点,和直径长度。直径的中点就是根节点,它的度数就是



x

x






x





,随便找个根节点直接相邻的节点



n

o

d

e

node






n


o


d


e





,其度数减一就是



y

y






y




#include <bits/stdc++.h>
#define oo 0x3f3f3f3f
#define ll long long
#define OO 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(false);cin.tie(nullptr)
#define endl "\n"
#define int ll
const int N = 2e5 + 10, M = 2 * N;
using namespace std;
typedef pair<int, int> pii;
#define deb(i,x) if(int i==x) int k = 1; 
#define all(x) x.begin(),x.end()
ll lowbit(ll x) { return x & -x; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qmi(ll a, ll b, ll mod) {
    ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; }
    return res;
}
int n, m;
struct node
{
    int v, ne;
}e[N];
int h[N] = { 0 }, tot = 0;
void add(int u, int v)
{
    e[++tot] = { v, h[u] }; h[u] = tot;
}
int mx1 = 0, id1 = 1, id2;
void dfs(int u, int fa, int de)
{
    if (de > mx1) mx1 = de, id1 = u;
    for (int i = h[u]; i; i = e[i].ne)
    {
        int v = e[i].v;
        if (v == fa)continue;
        dfs(v, u, de + 1);
    }
}

int k, to;
vector<int> ans, tt;
void dfs1(int u, int fa)
{
    if (u == id2) { ans = tt;}
    tt.push_back(u);
    for (int i = h[u]; i; i = e[i].ne)
    {
        int v = e[i].v;
        if (v == fa)continue;
        dfs1(v, u);
        tt.pop_back();
    }
}
signed main()
{
    IO;
    int t; cin >> t;

    while (t--)
    {
        tt.clear();
        tot = 0;
        id1 = 1, id2 = 1;
        mx1 = 0;
        cin >> n >> m;
        for (int i = 1; i <= n; i++)h[i] = 0;
        for (int i = 1; i <= m; i++)
        {
            int u, v; cin >> u >> v;
            add(u, v), add(v, u);
        }
        dfs(1, 0, 0);
        id2 = id1;
        mx1 = 0;
        dfs(id1, 0, 0);
        int de = mx1 + 1;
        k = de / 2 + 1;
        dfs1(id1, 0);
        to = ans[ans.size() / 2];
        int x = 0;
        for (int i = h[to]; i; i = e[i].ne)x++;
        int y = 0;
        for (int i = h[e[h[to]].v]; i; i = e[i].ne) y++;
        cout << x << ' ' << y - 1 << endl;
    }
    return 0;
}



G. Hits Different

题意:有一个塔状结构如图

在这里插入图片描述

对于输入的



n

n






n





,求出直接或间接位于



n

n






n





上方所有部分的和,每部分都是形如



i

2

i^2







i










2












的值。

思路:记忆化+容斥

对于输入的



n

n






n





,可以用二分求出它所在的层数的上一层是第几层,令其为



k

k






k





然后就可以分3种情况得到直接位于它上方的部分的值。

  • 第一种

位于当前层的第一个,直接在其上方的部分就一个,值为



k

(

k

+

1

)

/

2

k

+

1

k*(k + 1)/2-k+1






k













(


k




+








1


)


/2













k




+








1




  • 第二种

位于当前层最后一个,和第一种类似,其值为



k

(

k

+

1

)

k*(k +1 )






k













(


k




+








1


)





/2

  • 第三种

位于当前层第



d

d






d







KaTeX parse error: Undefined control sequence: \and at position 9: d \ne 1 \̲a̲n̲d̲ ̲d\ne最后一个

,直接在其上方的有两个。分别为



k

(

k

+

1

)

/

2

k

+

d

k*(k+1)/2-k+d






k













(


k




+








1


)


/2













k




+








d









k

(

k

+

1

)

/

2

k

+

d

1

k*(k+1)/2-k+d-1






k













(


k




+








1


)


/2













k




+








d













1




int vis[N] = { 0 };
int get(int n)
{
    int l = 1, r = 1e4;
    while (l < r)
    {
        int mid = (l + r + 1) >> 1;
        if ((mid + 1) * mid / 2 <= n) l = mid;
        else r = mid - 1;
    }
    if (l * (l + 1) / 2 == n) l--;
    return l;
}
int res[N] = { 0 };
 
int dfs(int n)
{
    if (res[n])return res[n];
    int ans = 0;
    int m = n;
    int k = get(m);
    int num = k * (k + 1) / 2;
    int d = m - num;
    ans += m * m;
    int cnt = 0;
    if (d != k + 1)
    {
        cnt++;
        int dd = dfs(num - k + d);
        ans += dd;
    }
    if (d != 1)
    {
        cnt++;
        int dd = dfs(num - k - 1 + d);
        ans += dd;
    }
    if (cnt == 2) {
        int up = num - k + d - 1;
        int floor = get(up);
        num = floor * (floor + 1) / 2;
        d = up - num;
        int dd = dfs(num - floor + d);
        ans -= dd;
    }
    return res[m] = ans;
}
signed main()
{
    IO;
    int t; cin >> t;
 
    while (t--)
    {
        int n; cin >> n;
        for (int i = 1; i <= n; i++)vis[i] = 0;
        vis[n] = 1;
        int ans = dfs(n);
        res[n] = ans;
        cout << ans << endl;
    }
    return 0;
}



H. Don’t Blame Me

DP

signed main()
{
    IO;
    const int mod = 1e9 + 7;
    int t; cin >> t;
    while (t--)
    {
        int n, k; cin >> n >> k;
        vector<int> a(n + 1);
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        vector dp(n + 1, vector<int>(100));
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            dp[i][a[i]] = 1;
            for(int j = 0; j <= 64; j++) {
                dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
                dp[i][j & a[i]] = (dp[i][j & a[i]] + dp[i - 1][j]) % mod;
        }
    }
        for(int i = 0;i < 64;i ++){
            int d = 0;
            for(int j = 0;j <= 5;j ++)
                if(i & (1 << j)) d ++;
            if(d == k)ans = (ans + dp[n][i]) % mod;
        }
        cout << ans % mod << endl;
    }
    return 0;
}



版权声明:本文为m0_65907991原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。