Codeforces Round #267 (Div. 2)

来源:互联网 发布:淘宝网儿童内衣 编辑:程序博客网 时间:2024/06/09 18:54

          昨晚又打了场div2,最近div2场怎么这么多……


467A - George and Accommodation

        不能更水……

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<set>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-8#define pi acos(-1.0)using namespace std;typedef long long ll;int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    int n,p,q;    int ans = 0;    scanf("%d",&n);    for(int i = 0;i < n;++i)    {        scanf("%d%d",&p,&q);        if(p + 2 <= q)            ans++;    }    printf("%d\n",ans);    return 0;}

467B - Fedor and New Game

        给出m+1个数,求第m+1个数和前面所有的数有多少个数,二进制表示下位数不同的数量 <= k。异或一下然后统计有多少个1即可,非常水。。。



#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<set>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-8#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn = 1000 + 10;int x[maxn];int getbit(int x){    int cnt = 0;    while(x)    {        cnt++;        x = x & (x-1);    }    return cnt;}int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    int n,m,k;    scanf("%d%d%d",&n,&m,&k);    for(int i = 0;i <= m;++i)        scanf("%d",&x[i]);    int ans = 0;    for(int i = 0;i < m;++i)    {        int y = x[i]^x[m];        if(getbit(y) <= k)            ans++;    }    printf("%d\n",ans);    return 0;}

467C - George and Job 

      从一个序列中选k个长度为m的序列,并且不能相交,求k个序列的和的最大值。dp就行了,dp[i][j]表示最后一个选的序列的结尾是i,此时选了j个的最大值。dp[i][j] = max(dp[k][j-1] + sum[i] - sum[i-m]),0 <= k <= i - m,用个数组保存一下最大值即可。开始用了二维数组保存最大值了,但是MLE了两发,太坑了,注意一下dp的顺序就可以用一维的数组来维护了。



#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<set>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-8#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn = 5000 + 5;int a[maxn];ll sum[maxn],dp[maxn][maxn],maxv[maxn];int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    int n,m,k;    scanf("%d%d%d",&n,&m,&k);    for(int i = 1;i <= n;++i)        scanf("%d",&a[i]);    sum[0] = 0;    for(int i = 1;i <= n;++i)        sum[i] = sum[i-1] + a[i];    memset(dp,0xff,sizeof(dp));    memset(maxv,0,sizeof(maxv));    dp[0][0] = 0;    for(int j = 1;j <= k;++j)    {        for(int i = 1;i <= n;++i)        {            if(i - m >= 0)            {                dp[i][j] = max(dp[i][j],maxv[i-m] + sum[i] - sum[i-m]);            }        }        for(int i = 1;i <= n;++i)            maxv[i] = max(maxv[i-1],dp[i][j]);    }    ll ans = 0;    for(int i = 1;i <= n;++i)        if(dp[i][k] != -1)            ans = max(ans,dp[i][k]);    printf("%I64d\n",ans);    return 0;}

467D - Fedor and Essay 

 

给出一个文章,由m个单词组成,再给出n对同义词a,b,表示a能被b替换(反之不成立),可以将给出的单词用同义词替换,要求最后文章中的字母r的数量最少,在这个前提下让文章所包含的字符数最少,单词不区分大小写。

比赛时没写完,太伤心。。。其实要用r尽量少并且长度小的单词尽量去替换给出的单词,如果对于每个单词预处理出来哪个单词替换它最优,那么就可以直接得出答案。可以考虑同义词中的最优的单词,如果从这个单词出发,那么能替换成这个单词的就要尽量替换成它,然后标记掉,标记掉的一定是最优的,那么接下来只需要寻找下一没标记的单词接着搜就好了。



#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<set>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-8#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn = 600000 + 10;map<string,int>mp;string s1,s2,str[100000 + 10];vector<int>G[maxn];int rnt[maxn],len[maxn],best[maxn];bool vis[maxn];struct Node{    int a,b,id;    Node(int a = 0,int b = 0,int id = 0):a(a),b(b),id(id){}    bool operator < (const Node & x) const    {        return (a == x.a && b > x.b) || (a > x.a);    }};priority_queue<Node>q;queue<int>que;inline void cal(int id,string s){    len[id] = s.length();    rnt[id] = 0;    for(int i = 0;i < len[id];++i)        if(s[i] == 'r') rnt[id]++;}int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    int m,n,cnt = 0;    cin>>m;    for(int i = 1;i <= m;++i)    {        cin>>s1;        int l = s1.length();        for(int j = 0;j < l;++j)            if(s1[j] >= 'A' && s1[j] <= 'Z')                s1[j] += 'a' - 'A';        str[i] = s1;        if(mp.find(s1) == mp.end())        {            cnt++;            mp[s1] = cnt;            cal(cnt,s1);        }    }    cin>>n;    int a,b;    for(int i = 0;i < n;++i)    {        cin>>s1>>s2;        int l = s1.length();        for(int j = 0;j < l;++j)            if(s1[j] >= 'A' && s1[j] <= 'Z')                s1[j] += 'a' - 'A';        l = s2.length();        for(int j = 0;j < l;++j)            if(s2[j] >= 'A' && s2[j] <= 'Z')                s2[j] += 'a' - 'A';        if(mp.find(s1) == mp.end())        {            cnt++;            mp[s1] = cnt;            cal(cnt,s1);        }        if(mp.find(s2) == mp.end())        {            cnt++;            mp[s2] = cnt;            cal(cnt,s2);        }        a = mp[s1];        q.push(Node(rnt[a],len[a],a));        b = mp[s2];        q.push(Node(rnt[b],len[b],b));        G[b].push_back(a);    }    for(int i = 1;i <= cnt;++i)        best[i] = i;    Node node;    while(!q.empty())    {        node = q.top();q.pop();        if(vis[node.id]) continue;        que.push(node.id);        while(!que.empty())        {            int u = que.front();que.pop();            if(vis[u]) continue;            vis[u] = true;            for(int i = 0;i < (int)G[u].size();++i)            {                int v = G[u][i];                if(vis[v]) continue;                best[v] = node.id;                que.push(v);            }        }    }    ll ans1 = 0,ans2 = 0;    for(int i = 1;i <= m;++i)    {        int id = mp[str[i]];        if(rnt[best[id]] < rnt[id] || (rnt[best[id]] == rnt[id] && len[best[id]] < len[id]))        {            id = best[id];        }        ans1 += rnt[id];        ans2 += len[id];    }    cout<<ans1<<" "<<ans2<<endl;    return 0;}

467E - Alex and Complicated Task 

        感觉这题还挺简单的,早知道可以先做做这题 。。。。题意大概就是要在一个序列中取出一个尽量长的子序列,满足给定的要求……

            从给定的要求中可以发现,要求的数组是每四个一组的,并且第1个和第3个相等,第2个和第4个相等,那么就有个贪心的过程,我们要构造这个序列,那么尽可能要取原序列中靠前的数字组成,这样才可能令序列尽量长。那么问题就变成了,当前原序列中s之前的都取完了,当前的位置是i,从这个区间中是否能选出满足要求的四个数,可以发现,如果这个区间有答案,那么第i个数一定要选,如果第i个数不选,那么说明s ~ i-1中就可以得到这4个数,那么在i-1的时候已经算出来了。

           想到这里,大概就有些思路了,我们发现num[i]这个数在区间中不会超过4个,因为4个相同的数字一定能
构造出一个解,预处理一个数组pre[i],表示与第i个数字相同并在它左边的第一个位置,那么就可以枚举一下第二个数的位置j了,接下来的问题就是查询s ~ j-1 和 j + 1~ i -1 中是否有相同的数字,这个可以用线段树搞一下,对于一个位置i,线段树的值是pre[i],那么就是要查询区间[j+1,i - 1]中的最小值是否小于j,如果小于j,那么就有解,注意为了保证查询的值大于等于s,在查询开始之前把小于s的值都删掉。


#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<set>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-8#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn = 500000 + 10;struct Node{    int a,b;    Node(int a = 0,int b = 0):a(a),b(b){}    bool operator < (const Node & x) const    {        return a > x.a;    }};int num[maxn],a[maxn],b[maxn],pre[maxn],last[maxn],ans[maxn],tot;int minv[maxn<<2],mpos[maxn<<2];priority_queue<Node>q;inline void PushUp(int rt){    if(minv[rt<<1] < minv[rt<<1|1])    {        minv[rt] = minv[rt<<1];        mpos[rt] = mpos[rt<<1];    }    else    {        minv[rt] = minv[rt<<1|1];        mpos[rt] = mpos[rt<<1|1];    }}void build(int l,int r,int rt){    minv[rt] = inf;    mpos[rt] = l;    if(l == r)        return ;    int m = (l + r)>>1;    build(l,m,rt<<1);    build(m+1,r,rt<<1|1);}void Update(int p,int l,int r,int rt,int v){    if(l == r)    {        minv[rt] = v;        return ;    }    int m = (l + r)>>1;    if(m >= p) Update(p,l,m,rt<<1,v);    else Update(p,m+1,r,rt<<1|1,v);    PushUp(rt);}int Query(int L,int R,int l,int r,int rt,int & p){    if(l >= L && r <= R)    {        p = mpos[rt];        return minv[rt];    }    int m = (l + r)>>1;    if(m >= R) return Query(L,R,l,m,rt<<1,p);    else if(m < L) return Query(L,R,m+1,r,rt<<1|1,p);    else    {        int r1,r2,p1,p2;        r1 = Query(L,R,l,m,rt<<1,p1);        r2 = Query(L,R,m+1,r,rt<<1|1,p2);        if(r2 < r1)            r1 = r2,p1 = p2;        p = p1;        return r1;    }}int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);    int n;    scanf("%d",&n);    for(int i = 1;i <= n;++i)    {        scanf("%d",&a[i]);        num[i] = b[i] = a[i];    }    sort(b + 1,b + n + 1);    int N = unique(b + 1, b + n + 1) - (b+1);    for(int i = 1;i <= n;++i)        a[i] = lower_bound(b + 1,b + N + 1,a[i]) - b;    memset(last,0xff,sizeof(last));    for(int i = 1;i <= n;++i)    {        if(last[a[i]] == -1)            pre[i] = 0;        else            pre[i] = last[a[i]];        last[a[i]] = i;    }    build(1,n,1);    tot = 0;    Node node;    int s = 1;    for(int i = 1;i <= n;++i)    {        while(!q.empty())        {            node = q.top();            if(node.a < s)            {                Update(node.b,1,n,1,inf);                q.pop();            }            else                break;        }        int cnt = 0;        int j = i;        while(j >= s)        {            j = pre[j];            cnt++;        }        if(cnt > 3)        {            ans[tot++] = num[i];            ans[tot++] = num[i];            ans[tot++] = num[i];            ans[tot++] = num[i];            s = i + 1;        }        else        {            j = pre[i];            while(j > s)            {                int pnow,plast;                if(j + 1 <= i - 1)                {                    plast = Query(j + 1,i - 1,1,n,1,pnow);                    if(plast < j)                    {                        ans[tot++] = num[plast];                        ans[tot++] = num[j];                        ans[tot++] = num[pnow];                        ans[tot++] = num[i];                        s = i + 1;                        break;                    }                }                j = pre[j];            }        }        Update(i,1,n,1,pre[i]);        q.push(Node(pre[i],i));    }    printf("%d\n",tot);    for(int i = 0;i < tot;++i)    {        if(i) putchar(' ');        printf("%d",ans[i]);    }    puts("");    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 有行车记录仪遇到碰瓷怎么办 狗换了主人不吃怎么办 遇到扔东西碰瓷怎么办 碰见碰瓷的人怎么办 开店遇上碰瓷的顾客怎么办 我刮到别人的车怎么办 新车被刮了漆怎么办 停车擦到别人车怎么办 骑自行车被汽车撞了怎么办 车停在小区被刮怎么办 机动车被自行车撞了怎么办 单车撞小车后被起诉怎么办 给小车撞到电动单车怎么办 车停在路边被自行车撞怎么办 撞了碰瓷的人怎么办 谷丙转氨酶46该怎么办 渣土车开飞机了怎么办 自己车撞自己车怎么办 撞了人没钱赔怎么办 闯红灯扣了6分怎么办 开共享汽车闯红灯了怎么办 新手如果不小心闯红灯怎么办 红绿灯左转车道直行了怎么办 跟着大车后面闯了红灯怎么办 宝宝私处好红怎么办呢 甲亢难怀孕怎么办才好 怀孕8周查出甲亢怎么办 电动车被交警拖走了怎么办 电动车车被城管拖走了怎么办 12123地理反编码失败怎么办 苹果手机地理反编码失败怎么办 城管执法过程被打怎么办 老婆看不起老公不让碰怎么办 老婆总不让碰该怎么办 机动车扣满12分怎么办 吊车吊运货物失控应该怎么办 车辆违章扣6分怎么办 最新交通法扣满12分怎么办 违章停车单丢了怎么办 违停告知单掉了怎么办 违章停车扣3分怎么办