Codeforces Round #256 (Div. 2) | 前4题

来源:互联网 发布:linux alias ll 编辑:程序博客网 时间:2024/06/07 07:13

A:

题意:

给你n个展柜,用于放奖杯和奖牌。

要求:

1.一个展柜最多能放5个奖杯或者10个奖牌

  2.奖杯和奖牌不能同时放在一个展柜。

问你能否可以把所有的奖杯和奖牌都放到n个展柜里。

特殊情况,奖杯或者奖牌为0的时候特判一下。

———————————————————————————————————————————————————

B:当时看到就吓尿,不过div2第2题应该还是水题,于是乎,耐心看了看。

题意:

need tree:第二个字符串的某些字母在第一个字符串中找不到。
第一个字符串能转换成第二个字符串的前提下:
array:仅需要调换顺序的。
automaton:仅需要删除某些字母。
both:既需要调换顺序也需要删除字母。


首先判一下是否能转换,不能转换输出need tree,结束。

然后判断长度是否相等,相等设标记automaton为0,不相等则为1。

最后暴力判断一下从第一个字符串所取的字符能否是按顺序取的,是则为0,否则为1;

———————————————————————————————————————————————————

C:后来做出来的,分治思想。一直认为dfs会不会超时。

题意:

给你一列栅栏,然后给出他们的高度。现在要粉刷栅栏,问你最少只用刷几次。刷子可以横着刷也可以竖着刷。


思路:

刷完n个fence,最多刷n次够了。每次横着刷尽量多次,然后就会出现许多没刷到的小状态。结果就是res = min(n, cot);

cot是当前状态下,横着刷的次数 + 解决每个小状态的最小刷次数。

———————————————————————————————————————————————————

D:感谢铭神指导!

题意:

给你一个乘法表,让你求出第几小的数。就是把所有的数sort一下,然后找出第k个数。原题题意有些坑。


思路:

由于数据这么大,是不可能一一算出来然后sort的。因此用二分。
可以自己先打个10x10的乘法表,观察一下数据。
数值范围是[1,100],二分得到50,找出小于等于50的数。
可以找到这样的规律,遍历一下行,复杂度O(n)。用50除以行数所得到的数,与列数相比,取其小值,即可得到该行<= 50的个数。我这里用getCot(50)获取个数。

如果getCot(50) < k,则往左移;getCot(50) >= k,则往右移(为什么这样,可以自己在纸上写写看)
由于等于k的时候一样是右移的,因此最终二分到的数肯定是getCot(r) = k-1,因此返回值是r+1.

———————————————————————————————————————————————————


B:

#include <cstdio>#include <cstring>#include <iostream>#include <cstdlib>using namespace std;#include <string>string t1, t2;int m1[30], m2[30], m3[30];int solvearray(){    int time[105];    int t = 0;    int mark[105];    memset(mark, 0, sizeof(mark));    for(int i = 0;i < t2.length(); i++)    {        char ch = t2[i];        for(int j = t,k = 0;k < t1.length(); j++, k++)        {            if(ch == t1[j]&&mark[j] != 1)            {                time[i] = j;                mark[j] = 1;                t = time[i];                break;            }            j %= t1.length();        }    }    for(int i = 0;i < t2.length()-1; i++)    {        if(time[i] > time[i+1])        {            //cout<<"fuck you ,here is time[i] > time[i+1]"<<endl;            return 1;        }    }    return 0;}int solveauto(){    if(t1.length() != t2.length())        return 1;    else        return 0;}int main(){    while(cin>>t1>>t2)    {        memset(m1,0, sizeof(m1));        memset(m2, 0, sizeof(m2));        memset(m3, 0, sizeof(m3));        for(int i = 0;i < t1.length(); i++)        {            m1[t1[i] - 'a'] ++;            m3[t1[i] - 'a'] ++;        }        for(int i = 0;i < t2.length(); i++)        {            m2[t2[i] - 'a'] ++;        }        int mark = 0;        for(int i = 0;i < t2.length(); i++)        {            if(m3[t2[i] - 'a'] < m2[t2[i] - 'a'])            {                printf("need tree\n");                mark = 1;                break;            }        }        if(mark)    continue;        //charge array        int c1 = solvearray();        int c2 = solveauto();        if(c1 == 1 && c2 == 1)            printf("both\n");        else if(c1 == 1)            printf("array\n");        else            printf("automaton\n");    }    return 0;}

C.

#include <cstring>#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;const int MAXN = 5005;int a[MAXN];int dfs(int l, int r){    if(l > r)   return 0;    int n = r - l + 1;    int minh = a[l];    int res = 0;    //cout<<"l = "<<l<<" r = "<<r<<endl;    for(int i = l;i <= r; i++)    {        minh = min(minh, a[i]);    }    for(int i = l;i <= r; i++)    {        a[i] -= minh;    }    res += minh;    int tl, tr, j;    for(int i = l; i <= r; i++)    {        if(a[i] != 0)        {            tl = i;            for(j = i; j <= r; j++)            {                if(a[j] == 0)                {                    tr = j-1;                    res += dfs(tl, tr);                    break;                }                if(j == r &&a[j] != 0)                {                    tr = j;                    res += dfs(tl, tr);                    break;                }            }            i = j;        }    }    return min(res, n);}int main(){    int n;    while(scanf("%d", &n) != EOF)    {        memset(a, 0, sizeof(a));        for(int i = 1;i <= n; i++)            scanf("%d", &a[i]);        int res = dfs(1, n);        cout<<res<<endl;    }    return 0;}

D.

#include <cstring>#include <cstdlib>#include <cstdio>#include <iostream>using namespace std;const int MAXN = 5005;//int cot[MAXN];//save the quanlity of lower than i;long long n, m, k;long long  getCot(long long  mid){    long long  res = 0;    for(int i = 1;i <= n; i++)    {        res += min(m,mid/i);    }    return res;}long long erfen(long long  l, long long r){    long long mid;    while(l <= r)    {        mid = (l+r) / 2;        if(getCot(mid) < k)            l = mid+1;        else             r = mid-1;    }    return r+1;}    int main(){        while(scanf("%I64d%I64d%I64d", &n ,&m, &k) != EOF)    {        cout<<erfen(1, n*m)<<endl;    }    return 0;}

0 0