zoukankan      html  css  js  c++  java
  • Codeforces Round #479 (Div. 3)解题报告

    题目链接:  http://codeforces.com/contest/977  

    A. Wrong Subtraction

    题意

    给定一个数x,求n次操作输出。操作规则:10的倍数则除10,否则减1

    直接写,手速题,没啥好说的

    B. Two-gram

    题意

    求出现次数最多的连续两个字符

    还是签到题,我居然很麻烦地用了map,= =算了,思路畅通都无所谓了

    #include <iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<string>
    #include<map>
    using namespace std;
    int main()
    {
        char a[100],s[5],ss[5];
        int n;
        while(cin>>n)
        {
            cin>>a;
            map<string,int>mp;
            int MAX=-1;
            for(int i=0;i<strlen(a)-1;i++)
            {
                s[0]=a[i];  s[1]=a[i+1];
                mp[s]++;
                //cout<<s<<endl;
                if(mp[s]>MAX) MAX=mp[s],ss[0]=a[i],ss[1]=a[i+1];
            }
            cout<<ss[0]<<ss[1]<<endl;
        }
        return 0;
    }
    View Code

    C. Less or Equal

    题意

    给一串数组,是否找到一个数x,找到k个数字<=x,找到输出x,不能输出-1。

    第二组,要找到两个数字,排序后出现1,3,3,会出现三个数字小于等于3,所以不能找到。

    注意下k==0的时候就好了,没啥好说的

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #define ll long long
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn];
    int main()
    {
        int m,k;
        while(cin>>m>>k)
        {
            for(int i=0;i<m;i++)
                cin>>a[i];
            sort(a,a+m);
            if(k==0)
            {
                if(a[0]==1) puts("-1");
                else cout<<a[0]-1<<endl;
            }
            else if(k==m) cout<<a[k-1]<<endl;
            else
            {
                if(a[k-1]==a[k]) puts("-1");
                else cout<<a[k-1]<<endl;
            }
        }
        return 0;
    }

    D. Divide by three, multiply by two

    题意

    直接看样例吧  4 8 6 3 12 9  把这个序列排成一个这样的序列, 前一位是后一位数的一半或者3倍,所以排序后是这样 9 3 6 12 4 8

    dfs或者直接双重for循环都可以,不过赛后看到个数学思路的题解,觉得很有灵性= =

    直接按对3有更多约数的多少来排(前一位是后一位的3倍),有相同个则从小到大(也就是前一位是后一位数的一半)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #define ll long long
    using namespace std;
    const int maxm=2e5+10;
    const int maxn=1e5+10;
    
    ll a[105];
    ll s(ll num)
    {
        ll cnt=0;
        while(num%3==0)
        {
            cnt++;
            num/=3;
        }
        return cnt;
    }
    bool cmp(ll x,ll y)
    {
        if(s(x)!=s(y))
            return s(x)>s(y);
        else return x<y;
    }
    int main()
    {
        int n;
        while(cin>>n)
        {
            for(int i=0;i<n;i++)
                cin>>a[i];
            sort(a,a+n,cmp);
            for(int i=0;i<n;i++)
                printf("%lld%c",a[i],i==n-1?'
    ':' ');
        }
    }

    E. Cyclic Components

    题意

    给定点的个数和各条边,问有多少个环

    既然是环,一个点就会对应两次啊,直接并查集啊,巴拉巴拉,水水水就过去了

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #define ll long long
    using namespace std;
    const int maxn=2e5+10;
    int pre[maxn],edg[maxn],cnt;
    struct node
    {
        int u,v;
    }a[maxn];
    void iint()
    {
        for(int i=0;i<maxn;i++)  pre[i]=i;
    }
    int ffind(int x)
    {
        if(x==pre[x])  return x;
        return pre[x]=ffind(pre[x]);
    }
    void join(int x,int y)
    {
        x=ffind(x),y=ffind(y);
        if(x!=y)  pre[x]=y;
        else cnt++;
    }
    int main()
    {
        int m,n;
        while(cin>>m>>n)
        {
            iint();
            memset(edg,0,sizeof(edg));
            for(int i=0;i<n;i++)
            {
                cin>>a[i].u>>a[i].v;
                edg[a[i].u]++;
                edg[a[i].v]++;
            }
            cnt=0;
            for(int i=0;i<m;i++)
            {
                if(edg[a[i].u]==2&&edg[a[i].v]==2)
                    join(a[i].u,a[i].v);
            }
            cout<<cnt<<endl;
        }
        return 0;
    }

    F. Consecutive Subsequence

    题意

    给你一个数组找出最长的递增子序列的长度以及下标位置。

    例如:  第一组样例 3 3 4 7 5 6 8

        最长的子序列为3 4 5 6,长度为4。

        下标为1 3 5 6或2 3 5 6

    觉得dp才是正解,贴个别人的http://www.bubuko.com/infodetail-2595514.html

    可是比赛时候不知道为什么被我map玄学给过了2333

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #define ll long long
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn];
    int main()
    {
        ios::sync_with_stdio(false);
        int n,tmp;
        while(cin>>n)
        {
            map<int,int>mp;
            int max_pos=-1,Max=-1;
            for(int i=1;i<=n;i++)
            {
                cin>>a[i];
                mp[a[i]]=mp[a[i]-1]+1;
                if(mp[a[i]]>Max)    Max=mp[a[i]],tmp=a[i],max_pos=i;
            }
            int u=tmp-Max+1;
            cout<<Max<<endl;
            bool f=true;
            for(int i=1;i<=max_pos;i++)
            {
                if(a[i]==u)
                {
                    if(f) cout<<i,f=false;
                    else cout<<" "<<i;
                    u++;
                }
            }
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Partition HDU
    FFT版题 [51 Nod 1028] 大数乘法
    [51Nod 1220]
    [bzoj 4176] Lucas的数论 (杜教筛 + 莫比乌斯反演)
    [51Nod 1222]
    [51Nod 1227] 平均最小公倍数 (杜教筛)
    算法-05-二分查找第一个出现的数 美团一面
    Hbase-00-MAC 安装Hbase 单机模式
    算法-04-用两个栈实现队列
    算法-03-Java 实现阻塞队列 字节三面算法题
  • 原文地址:https://www.cnblogs.com/weimeiyuer/p/9037016.html
Copyright © 2011-2022 走看看