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

    http://codeforces.com/contest/864

    第一次打cf的月赛……

    A

    题意:给你一个数列,问你能不能保证里面只有两种数且个数相等。2<=n<=100,1<=ai<=100。

    水……没看完题就交了结果YES的时候还要输出这两种数是什么,然后就+1了……

    #include <iostream>
    #define maxn 105
    using namespace std;
    int n,a,t[maxn],c[maxn],d[maxn];
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a;
            t[a]++;
        }
        int cnt=0;
        for(int i=1;i<=100;i++)
        {
            if(t[i])
            {
                c[++cnt]=t[i];
                d[cnt]=i;
            }
        }
        if(cnt!=2)
            cout<<"NO";
        else if(c[1]!=c[2])
            cout<<"NO";
        else
            cout<<"YES"<<endl<<d[1]<<' '<<d[2];
        return 0;
     } 

    B

    题意:给你一个只含字母的字符串,求仅由小写字母构成的最长子串。

    从左到右扫一遍同时记录长度len,遇到大写字母就更新答案并把len归零就好了。一遍过。

    #include <iostream>
    #include <string>
    #include <cctype>
    #include <cstring>
    using namespace std;
    int n;
    string s;
    bool used[300];
    int main()
    {
        cin>>n>>s;
        int len=0,cnt=0,ans=0;
        for(int i=0;i<n;i++)
        {
            if(isupper(s[i]))
            {
                memset(used,false,300);
                len=0;
                cnt=0;
            }
            else
            {
                len++;
                if(!used[s[i]])
                {
                    used[s[i]]=true;
                    cnt++;
                    ans=max(ans,cnt);
                }
            }
        }
        cout<<ans;
        return 0;
    }

    C

    题意:一条直线道路,起点为0,终点为a,有一辆车在起点和终点来回开k次(来算一次,回算一次)。车的油箱有b汽油,每走1路程就耗1汽油。在路上f的位置有一个加油站,可以帮你把油箱加满。问要完成这k次来回最少需要加多少次油。

    如果车现在停在加油站,并且油还够开到终点(或者起点)再回头开到加油站,那么显然不用加油。

    干脆把加油站当作检查点,每次检查下还剩多少油,判断需不需要加油。k次以后输出结果。如果加了油也回不来加油站,那么输出-1。要注意特判第一回还有最后一回。

    四遍才过……

    #include <iostream>
    using namespace std;
    int a,b,f,k;
    int main()
    {
        cin>>a>>b>>f>>k;
        int ans=0,pet=b-f;
        if(pet<0)
        {
            cout<<-1;
            return 0;
        }
        bool ahead=true;
        for(int i=1;i<k;i++)
        {
            if(ahead)
            {
                if(pet-2*(a-f)>=0)
                    pet-=2*(a-f);
                else
                    pet=b-2*(a-f),ans++;
            }
            else
            {
                if(pet-2*f>=0)
                    pet-=2*f;
                else
                    pet=b-2*f,ans++;
            }
            ahead^=1;
            if(pet<0)
            {
                cout<<-1;
                return 0;
            }
        }
        if(ahead)
        {
            if(pet-(a-f)<0)
            {
                if(b-(a-f)>=0)
                    ans++;
                else
                {
                    cout<<-1;
                    return 0;
                }
            }
        }
        else
        {
            if(pet-f<0)
            {
                if(b-f>=0)
                    ans++;
                else
                {
                    cout<<-1;
                    return 0;
                }
            }
        }
        cout<<ans;
        return 0;
    }

    D

    题意:给你一个n项数列,里面的数字均在1~n范围内,问最少替换多少个数字才能变成一个1~n的排序,输出字典序最小的方案。

    细节貌似有点多,还没做出来……

    E

    题意:有n个物品,每个物品价值为pi,拿起来要ti的时间,但是这个物品在时间大于等于di时就不能拿了。问怎样使拿到的物品价值之和最大。

    容易看出这是道傻逼背包题,得f(i,j)=max{f(i-1,j), f(i-1,j-t[i])+p[i]} (j<d[i]且j>=t[i]),答案就是max{f(n,x) | 0<=x<=2000}。

    当时还不懂怎么输出方案,比赛完了才想到每次转移记录一下,然后从答案开始逆过来找哪个物品被拿了。

    然后交了上去,WA了。跑去看下别人的AC代码,发现别人都对物品按照di升序排序再选了。我也试了一发,交上去马上就A了。

    之后才想明白,f(i,j)是按照1,2,...,i的顺序选择物品得到的价值最大值,如果不排序就会导致有些在后面但是d很小的物品选不到。

    #include <iostream>
    #include <stack>
    #include <algorithm>
    using namespace std;
    int n;
    struct item { int t, d, p, id; } a[105];
    bool cmp(const item& x, const item& y) { return x.d < y.d; }
    int dp[105][2005];
    bool took[105][2005];
    int main()
    {
        ios::sync_with_stdio(false);
        int ans = 0;
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            a[i].id = i;
            cin >> a[i].t >> a[i].d >> a[i].p;
        }
        sort(a + 1, a + 1 + n, cmp);
        for (int i = 1; i <= n; i++)
        {
            ans = 0;
            for (int j = 1; j <= 2005; j++)
            {
                if (j < a[i].d && j >= a[i].t && dp[i - 1][j - a[i].t] + a[i].p >= dp[i - 1][j])
                {
                    dp[i][j] = dp[i - 1][j - a[i].t] + a[i].p;
                    took[i][j] = true;
                }
                else
                    dp[i][j] = dp[i - 1][j];
    
                if (dp[i][j] >= dp[i][ans])
                    ans = j;
            }
        }
        cout << dp[n][ans] << endl;
        stack<item> s;
        int j = ans;
        for (int i = n; i >= 1; i--)
        {
            if (took[i][j])
            {
                s.push(a[i]);
                j -= a[i].t;
            }
        }
        cout << s.size() << endl;
        while (!s.empty())
        {
            cout << s.top().id << ' ';
            s.pop();
        }
        return 0;
    }

    未完待+1s(可能)

  • 相关阅读:
    RMAN 与control文件和spfile文件的备份
    Oracle 在 多个Virtualbox 虚拟机间 跨不同物理宿主机进行通信
    如何看数据库是否处在force_logging模式下
    Dataguard学习笔记
    Oracle数据库无法向listener注册的解决一例
    [Oracle]ORA-01499的处理
    查询红帽linux/Oracle Linux的发行版本的方法
    表空间的自动扩展是文件单位的
    [Oracle]如何查看一个数据文件是否是自动扩展
    创建表空间时ora-01119和ora-27040的处理
  • 原文地址:https://www.cnblogs.com/ssttkkl/p/7603566.html
Copyright © 2011-2022 走看看