zoukankan      html  css  js  c++  java
  • Codeforces Round #612 (Div. 2)

    A

    题意:罗里吧嗦,什么开始时候有a和b两种人,a这种人每过一秒会把右边如果是b种人就会把他变成a,

    不就是求A后面的P最长连续有几个?

    int n;
    char s[200005];
    
    void test_case() {
        scanf("%d%s", &n, s + 1);
        int cnt = 0, ans = 0;
        int b = 1;
        while(b <= n && s[b] == 'P')
            ++b;
        for(int i = b; i <= n; ++i) {
            if(s[i] == 'P')
                ++cnt;
            else {
                ans = max(ans, cnt);
                cnt = 0;
            }
        }
        ans = max(ans, cnt);
        printf("%d
    ", ans);
    }

    B - Hyperset

    题意:每个属性只有3种值。定义三张牌是一个SET,

    aaaa

    bbbb

    cccc

    每一列的的字母当他们要么全等要么两两不同。

    题解:枚举两张牌,可以确定第三张牌,放到

    unordered_map里面查找
    #include <bits/stdc++.h>
    #define MIN(a,b) ((((a)<(b)?(a):(b))))
    #define MAX(a,b) ((((a)>(b)?(a):(b))))
    #define ABS(a) ((((a)>0?(a):-(a))))
    using namespace std;
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<PII> VPII;
    typedef vector<LL> VL;
    typedef pair<LL,LL> PLL;
    typedef vector<PLL> VPLL;
    
    int main(void) {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
        int n,m;
        cin>>n>>m;
        unordered_map<string,int> qwq;
        qwq.clear();
        string s[n+1];
        for(int i=0;i<n;++i){
            cin>>s[i];
            qwq[s[i]]=i+1;
        }
        int ans=0;
        for(int i=0;i<n-2;++i)
            for(int j=i+1;j<n-1;++j){
                string ss;
                for(int k=0;k<m;++k){
                    if (s[i][k]==s[j][k]) ss+=s[i][k];
                    else if (s[i][k]!='S'&&s[j][k]!='S') ss+='S';
                    else if (s[i][k]!='T'&&s[j][k]!='T') ss+='T';
                    else if (s[i][k]!='E'&&s[j][k]!='E') ss+='E';
                }
                if (qwq[ss]>j) ++ans;
            }
        cout<<ans<<endl;
        return 0;
    }
    

      C

    心模拟了半天,最后放弃了

    题意
    给你一串从1−n 1-n1−n的序列,其中部分未知(表示为0),补全序列使得相邻数值奇偶性相反的数量最少
    相邻数值的奇偶性相反:两个相邻的两个数值,其中一个为奇数另外一个为偶数

    分析
    一开始用了贪心,结果卡在第十二个样例,然后改成dp
    定义dp数组如下

    int dp[120][60][2];
    dp[i][j][0/1] 表示第i+1个位置放了偶/奇数,且到第i+1处总共放了j个奇数,有多少个奇偶性相反
    1
    2
    得到状态转移方程

    dp[i][j][1] = min(dp[i - 1][j - 1][0] + 1, dp[i - 1][j - 1][1]);
    dp[i][j][0] = min(dp[i - 1][j][1] + 1, dp[i - 1][j][0]);
    1
    2
    当然这得看这个位置本身是不是已经有了数值,如果为0则两个都需要,如果已经有数值了就按照原来的数值进行dp

    #include <bits/stdc++.h>
    using namespace std;
    void solve() {
        int n;
        int dp[120][60][2], v[120];
        cin>>n;
        for(int i=0;i<n;++i) {
            cin >> v[i];
        }
        memset(dp, 0x3f, sizeof(dp));
        if(v[0] == 0)
            dp[0][1][1] = dp[0][0][0] = 0;
        else
            dp[0][v[0] & 1][v[0] & 1] = 0;
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j <= min(i + 1, (n + 1) / 2); ++j) {
                if ((v[i] & 1 || v[i] == 0) && j > 0)
                    dp[i][j][1] = min(dp[i - 1][j - 1][0] + 1, dp[i - 1][j - 1][1]);
                if (!(v[i] & 1))
                    dp[i][j][0] = min(dp[i - 1][j][1] + 1, dp[i - 1][j][0]);
            }
        }
        cout << min(dp[n-1][(n+1)/2][1], dp[n-1][(n+1)/2][0]) << endl;
    }
     
    int main() {
        solve();
        return 0;
    }
    

      D

    给出一棵有根树,每个节点都有一个权值,代表的是在其子树中有多少个节点的val比他小,现在要求根据每个点的权值构造出1~n的val数列

    输入,p,c;p表示该点的父亲在第p层,c表示该点的子树里面c个小于该点的值。
    思路:
    首先证明:n个节点一定可以用1-n的数字去放。因为1-n的数字都是不同的,那么不会有相对大小的问题,不会有节点之间相互影响而导致答案错误。放相同值的节点也就是少一个差值,我们完全可以用放的方式去避免,比如小的放在大的上面。
    其次证明:如果节点的C值小于节点的size(这个点包括他的子树总共有多少个点),那么一定存在这种方案,所以出现c值大于节点size肯定是不存在的。
    我们从顶点开始放,因为我们放1到n的数字,那么有多少个数字没放是一定的,所以我们相当于是从没放的数字当中找第C+1大的数字放上去,然后标记放的数字,向下递归。一定满足。

    #include<bits/stdc++.h>
    
    #define TEST freopen("C:\Users\hp\Desktop\ACM\in.txt","r",stdin);
    #define mem(a,x) memset(a,x,sizeof(a))
    #define debug(x) cout << #x << ": " << x << endl;
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    
    using namespace std;
    typedef long long ll;
    
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    const int maxn = 1e6+5;
    
    
    int n;
    vector<int>edge[maxn];
    int ans[maxn],c[maxn],vis[maxn],siz[maxn];
    void dfs(int u)
    {
        siz[u]=1;
        int sum=0,k;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
                sum++;
            if(sum==c[u]+1)
            {
                k=i;
                break;
            }
        }
        ans[u]=k;
        vis[k]=1;
        for(auto to:edge[u])
        {
            int v=to;
            dfs(v);
            siz[u]+=siz[v];
        }
        if(c[u]>siz[u]-1)
        {
            cout<<"NO
    ";
            exit(0);
        }
    }
    int main()
    {
        int root=0;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int fa;
            cin>>fa>>c[i];
            if(fa==0)
                root=i;
            else
                edge[fa].push_back(i);
        }
        dfs(root);
        cout<<"YES
    ";
        for(int i=1;i<=n;i++)
        {
            cout<<ans[i]<<" ";
        }
        cout<<"
    ";
    }
    

      

  • 相关阅读:
    中国登山队员首次登上地球之巅珠穆朗玛峰的时间与意义及影响 (转)
    兰戈利尔人(斯蒂芬.金)
    冥界系列一:麝月 (作者:钱其强)
    席慕容独白
    【心理寓言】小偷在鸡舍偷了只鸡
    美国恐怖故事第一季事件时间表
    大学生逃课的暴笑理由
    原来他们四个也是有故事的男人
    爆笑:七八十年代各地最流行顺口溜 网友:太经典了
    中国的世界之最
  • 原文地址:https://www.cnblogs.com/hgangang/p/12189983.html
Copyright © 2011-2022 走看看