Codeforces Round #227 (Div. 2)

来源:互联网 发布:淘宝可以改会员名吗 编辑:程序博客网 时间:2024/06/05 20:22

A. George and Sleep

题意:给你终止时刻和经历时间,问起始时刻。

#include<iostream>#include<cstdio>using namespace std;int main(){    //freopen("in.txt","r",stdin);    int s1,s2,t1,t2,ans1,ans2;    scanf("%d:%d",&s1,&s2);    scanf("%d:%d",&t1,&t2);    if(s2<t2)s2+=60,s1-=1;    if(s1<t1)s1+=24;    ans2=s2-t2;    ans1=s1-t1;    printf("%02d:%02d\n",ans1,ans2);    return 0;}

B. George and Round

题意:已经有m道题,一共需要n道题,每道题都有复杂度,大复杂度可以降低为小复杂度,问至少还要重新编多少道题才能满足要求。

思路:从后往前遍历,只要>=就能满足要求。

#include<iostream>#include<cstdio>using namespace std;const int maxn=3030;int n,m;int a[maxn],b[maxn];int main(){    //freopen("in.txt","r",stdin);    cin>>n>>m;    for(int i=1;i<=n;i++)cin>>a[i];    for(int i=1;i<=m;i++)cin>>b[i];    int ans=n;    int i=n,j=m;    while(i>=1&&j>=1)    {        if(a[i]<=b[j]){ans--;i--;j--;}        else if(a[i]>b[j])i--;    }    cout<<ans<<endl;    return 0;}

C. George and Number

贪心,如果比较的l==r-1就直接比较前面一长段和这一段。l!=r-1就比较l是否大于r-1即可。

#include <iostream>#include <string>using namespace std;string s;bool concat(int l,int r){    if(l!=r-l)        return l>r-l;    else        return s.substr(0,l)>=s.substr(l,r-l);}int main(){    while(cin>>s)    {        int l = s.length()-1;        int r = s.length();        int ans = 0;        while(l>=0)        {            if(s[l]!='0')            {                if(concat(l,r))                {                    r = l;                    ans++;                }            }            l--;        }        cout<<ans+1<<endl;    }    return 0;}

E. George and Cards

题目大意:给出一个长度为n的序列,然后在给出一个长度为k的条件序列,要求将原先的删除n-k个后得到的序列满足条件序列,条件序列b[i],表示序列的前i个元素中必须包含有b[i]这个数。删除操作,选取一个区间,删除中间的最小值,并且获得相应的区间长度的奖励,问说最多可以获得多少奖励


解题思路:二分+树状数组。首先,可以分析的出结论,b数组即为原先数组删除n-k个后的目标数组(想一下就知道的b[1]的位置肯定是放值为b[1]的卡片,那么值为b[2]的卡片就只能放在2上,以次类推);其次,为了得到尽量多的奖励,在删除元素时选取的区间就要尽量长,不仅如此,在删除元素时也要从小的开始删除,因为删除大的会导致删除小的时候区间长度的缩短;这样的话就可以通过将序列每个数按照从小到大的顺序将位置放入set中,碰到需要删除的元素就去二分上下限。知道上下限就可以通过BIT求得中间存在元素的个数。

#include<iostream>#include<set>#include<cstdio>#include<cstring>using namespace std;const int maxn=1000005;typedef long long LL;int p[maxn],b[maxn],tree[maxn];int n,k,a;void add(int x,int v){    while(x<=n)    {        tree[x]+=v;        x+=x&(-x);    }}LL sum(int x){    int ans=0;    while(x>0)    {        ans+=tree[x];        x-=x&(-x);    }    return ans;}void solve(){    set<int> s;    set<int>::iterator iter;    LL ans=0;    s.insert(0),s.insert(n+1);    for(int i=1;i<=n;i++)    {        if(b[i])        {            s.insert(p[i]);            continue;        }        iter=s.upper_bound(p[i]);        int r=*iter-1;        int l=*(--iter);        ans+=sum(r)-sum(l);        add(p[i],-1);    }    cout<<ans<<endl;}int main(){    //freopen("in.txt","r",stdin);    cin>>n>>k;    memset(tree,0,sizeof(tree));    memset(b,0,sizeof(b));    memset(p,0,sizeof(p));    for(int i=1;i<=n;i++)    {        cin>>a;        p[a]=i;        add(i,1);    }    for(int i=1;i<=k;i++)    {        cin>>a;        b[a]=1;    }    solve();    return 0;}


0 0
原创粉丝点击