码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces round #612解题报告A~D

时间:2020-01-31 19:18:21      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:==   its   pre   位置   字符   print   exit   class   hyper   

codeforces round #612解题报告A~D

A. Angry Students

  • 分析一下题意其实就可以发现是找\(A\)后面最长连续的\(P\)有多少个。
#include<bits/stdc++.h>
using namespace std;
void solve()
{
    int n;
    cin >> n;
    string str;
    cin >> str;
    int ans = 0;
    for(int i = 0; i < n; i++)
    {
        if(str[i] == 'A')
        {
            for(int j = i+1; j < n; j++)
            {
                if(str[j] == 'A') break;
                else ans = max(ans, j - i);
            }
        }
    }
    cout << ans << endl;
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--) solve();
    return 0;
}

B. Hyperset

  • 这题有个好处就是他的Feature只有三个,所以可以枚举两个字符串,确定出第三个字符串,之后看看有没有另一个就行。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1500 + 10;
typedef long long ll;
string s[maxn];
int n, k;
map<string, int> mp;
int main()
{
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++)
    {
        cin >> s[i];
        mp[s[i]]++;
    }
    int all = 'S' + 'E' + 'T';
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = i+1; j <= n; j++)
        {
            string tmp = "";
            for(int t = 0; t < k; t++)
            {
                if(s[i][t] == s[j][t])
                    tmp += s[i][t];
                else tmp += all - s[i][t] - s[j][t];
            }
            ans += mp[tmp];
        }
    } cout << ans / 3 << endl;
    return 0;
}

C. Garland

  • 这题只用关注奇偶性就行。
  • \(f(i,j,k,2)\)表示考虑到第\(i\)位剩\(j\)个奇数和\(k\)个偶数,上一个数的奇偶性是什么(0表示奇数,1表示偶数),得到的最小值。
  • 如果当前位置为奇数:
    • \(f(i,j,k,0)=min(f(i-1,j-1,k,0),f(i-1,j-1,k,1)+1)\).
  • 偶数同理。
  • 对于\(0\)的位置,奇数偶数都可以。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e2 + 10;
int a[maxn], n;
int f[maxn][maxn][maxn][3];
int odd, even;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    even = n/2, odd = n-even;
    memset(f, 0x3f, sizeof(f));
    f[0][0][0][0] = f[0][0][0][1] = 0;
    int k;
    for(int i = 1; i <= n; i++)
    {
        if(a[i])
        {
            if(a[i]&1)
            {
                for(int j = 1; j <= i; j++)
                {
                    k = i - j;
                    f[i][j][k][1] = min(f[i-1][j-1][k][1], f[i-1][j-1][k][0]+1);
                }
            }
            else
            {
                for(int j = 0; j < i; j++)
                {
                    k = i - j;
                    f[i][j][k][0] = min(f[i-1][j][k-1][0], f[i-1][j][k-1][1]+1);
                }
            }
        }
        else
        {
            for(int j = 1; j <= i; j++)
            {
                k = i - j;
                f[i][j][k][1] = min(f[i-1][j-1][k][1], f[i-1][j-1][k][0]+1);
            }
            for(int j = 0; j < i; j++)
            {
                k = i - j;
                f[i][j][k][0] = min(f[i-1][j][k-1][0], f[i-1][j][k-1][1]+1);
            }
        }
    }
    cout << min(f[n][odd][even][0], f[n][odd][even][1]) << endl;
    return 0;
}

D. Numbers on Tree

题意:

  • 给定一颗有根树,节点编号为\(1\)\(n\),每个节点上有一个值\(a_i\),一个人计算了\(c_i\),这个\(c_i\)表示子树中所有节点\(j\),有\(a_j<a_i\)的数量。

  • 现在只知道有一棵树,知道节点的父亲节点和他的\(c_i\),构造原始的\(a_i\)

思路:

  • 先考虑一个节点\(x\),他的子节点为叶子节点,假设说他有\(n\)个子节点,他的\(c_i=m\)
  • 这种情况就相对容易一些了,直接构造\(m\)个儿子为\(1,2,3,...,m\),然后自己为\(m+1\),剩下的儿子为\(m+2,...,n+1\)
  • 那么对于节点\(x\)的父亲节点,那么往中间找个位置插一下就行。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3 + 10;
int n, c[maxn], rt, a[maxn];
vector<int> son[maxn];

vector<int> dfs(int x)
{
    vector<int> ans, res; ans.clear();
    for(auto y : son[x])
    {
        vector<int> tmp = dfs(y);
        for(auto t : tmp)
            ans.push_back(t);
    }

    if(ans.size() < c[x]) {puts("NO"); exit(0);}
    for(int i = 0; i < c[x]; i++) res.push_back(ans[i]);
    res.push_back(x);
    for(int i = c[x]; i < ans.size(); i++) res.push_back(ans[i]);
    return res;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1, f, w; i <= n; i++)
    {
        scanf("%d%d", &f, &w);
        c[i] = w; son[f].push_back(i);
    } vector<int> ans = dfs(0);
    puts("YES");
    for(int i = 0; i < ans.size(); i++)
        a[ans[i]] = i+1;
    for(int i = 1; i <= n; i++)
        printf("%d ", a[i]);
    return 0;
}

codeforces round #612解题报告A~D

标签:==   its   pre   位置   字符   print   exit   class   hyper   

原文地址:https://www.cnblogs.com/zxytxdy/p/12245998.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!