czl蒻蒟的OI之路9

来源:互联网 发布:健身能保持年轻吗 知乎 编辑:程序博客网 时间:2024/05/17 03:44

  • XJOI奋斗群蒻蒟群群赛10 RANK排名7
      • T1Chess TourneyWA一次后AC
          • 题意
          • 分析过程
          • 给出题解
      • T2Luba And The TicketWA两次后AC
          • 题意
          • 分析过程
          • 给出题解
      • T3Two TVs WA一次后AC
          • 题意
          • 分析过程
          • 给出题解
      • T4Driving Test WA六次之后AC
          • 题意
          • 分析过程
          • 给出题解
      • T5Fire in the City
          • 题意
          • 分析过程
          • 给出题解
      • T6Guards In The Storehouse
          • 题意
          • 分析过程
          • 给出题解
      • T7Shortest Path Problem
          • 题意
          • 分析过程
          • 给出题解
      • 蒻蒟的总结

—>XJOI奋斗群(蒻蒟群)群赛10<— RANK排名7

T1:Chess Tourney(WA一次后AC)

题意:

给你一个数组,有2*n个元素。让你把这个数组分成两部分,要求不管怎么取这两个数组中的元素,第一部分都要大于第二部分,问是否能够分成这样。

分析过程:

由于是要随机取都必须满足,我们就先把数组从大到小排序,分别取第i(i<=n)个和第2*n-i+1个元素进行比较,如果结果是大于的,就继续,否则输出NO。

给出题解:
#include<bits/stdc++.h>using namespace std;bool cmp(int a,int b){    return a>b;}int main(){    int n,ans;    int a[205];    int cnt=0;    cin>>n;    for(int i=1;i<=2*n;i++)cin>>a[i];    sort(a+1,a+1+2*n,cmp);//  for(int i=1;i<=2*n;i++)cout<<a[i]<<" ";    for(int i=1;i<=2*n;i++)    {        if(a[i]>a[2*n+1-i])        {            cnt++;        }        if(cnt==n)        {            cout<<"YES"<<endl;            return 0;        }    }//  cout<<cnt<<endl;    cout<<"NO"<<endl;    return 0;}

T2:Luba And The Ticket(WA两次后AC)

题意:

有一个长度为6的数字串,要求你改变这里面的任意几个数字,让它的前三位和后三位加起来的和相同。求最少改变的数字个数

分析过程:

先计算数字串前三个与后三个的和是否相等,如果不相等,就把较小的字符串从小到大排序,计算每个数字与9的差(这个值就是这个数字改变之后能够使数字串的和增加的值)。然后用原来的和加上这些值,一旦和大于等于另三个数字的和,那么就break,输出加上数字的个数。

给出题解:
#include<bits/stdc++.h>using namespace std;int n,b,a[10],sum;char c;bool cmp(int a,int b){    return a>b;}int main(){    for(int i=1;i<=6;i++)    {        cin>>c;        a[i]=c;        a[i]-='0';    }    b=a[1]+a[2]+a[3]-a[4]-a[5]-a[6];    if(b!=0)    {        int i=0;        if(b>0)        {            a[4]=9-a[4];a[5]=9-a[5];a[6]=9-a[6];            sort(a+1,a+7,cmp);            while(sum<b)            {                i++;                sum+=a[i];            }        }        else        {            b=-b;            a[1]=9-a[1];a[2]=9-a[2];a[3]=9-a[3];            sort(a+1,a+7,cmp);            while(sum<b)            {                i++;                sum+=a[i];            }        }        cout<<i;    }    else cout<<0;;    return 0;}

T3:Two TVs (WA一次后AC)

题意:

简单来说,就是给你一棵树,让你把这颗树分成3段,每段的所有节点的和都相等。让你求是否有这种方案。如果有,就输出切割的点,如果没有就输出-1。

分析过程:

这题可以不用建树,用邻接表也同样可以做出来。只要从一个叶子节点向上遍历,搜索到这个节点的和路径上的所有点的和达到一定值就记录该节点,并将ans归零,继续搜索。如果搜索完之后只搜索到一个切割的带你,就输出-1,否则输出切割的两个点。

给出题解:
#include<bits/stdc++.h>#define maxn 1000050using namespace std;int n,sum,l,tem[maxn],ans,x=0,f[maxn],cut=0,node,cut1;struct tree{    int next;    int to;}a[maxn];void add(int c,int d){    x++;    a[x].to=d;    a[x].next=f[c];    f[c]=x;}void dfs(int c){    int d=c;    c=f[c];    while(c!=-1)    {        dfs(a[c].to);        tem[d]+=tem[a[c].to];        c=a[c].next;//      cout<<tem[d]<<endl;    }    if(tem[d]==ans&&d!=node)    {        if(cut==0)        {        cut++;        tem[d]=0;        cut1=d;        }        else         {        cut++;        cout<<cut1<<" "<<d;        exit(0);        }    }}int main(){//  freopen("in.txt","r",stdin);    memset(f,-1,sizeof(f));    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d%d",&l,&tem[i]);        if(l!=0)        add(l,i);        if(l==0)        node=i;        ans+=tem[i];    }//  cout<<"node="<<node<<endl;    if(ans%3!=0)    {        printf("-1\n");        exit(0);    }    else ans=ans/3;    dfs(node);//  cout<<cut<<endl;    if(cut!=2)    {        printf("-1\n");        exit(0);    }}

T4:Driving Test (WA六次之后AC)

题意:

一个人要去考驾照,考试时有四种指示,分别是限速,允许超车,不限速,不允许超车。这个人在考试时会有6种操作,分别为变速(1),超车(2),经过限速牌(3),经过允许超车牌(4),经过不限速牌(5),经过不允许超车牌(6)。这个人在考试时可能会违反几次交通规则,问这个人得说他忽视了多少交通指示牌才能通过考试。

分析过程:

先设这个人需要忽视的牌子的个数为cnt。对于违反了几次超车的牌子比较简单,只要设一个overtake,每经过一个不允许超车的牌子就++,如果经过一个允许超车的牌子就清零,如果在不允许超车的路段,这个人超车了,就用cnt+overtake,并把overtake清零。但对于限速就可以用栈了。如果遇到限速牌,就把限速牌入栈。如果遇到变速牌,就把栈中元素一个一个出栈,如果栈顶元素的speed值大于当前的速度,就可以直接出栈,反之,就cnt++后出栈,最后输出cnt的值。

给出题解:
#include<bits/stdc++.h>using namespace std;#define inf 5000int sign,change,limit;int overtake=0;int speed=inf;int main(){    stack<int >q;    long long n;    cin>>n;    int cnt=0;    for(int i=1;i<=n;i++)    {        scanf("%d",&sign);        if(sign==1)        {            scanf("%d",&change);            speed=change;            while(q.empty()==false&&q.top()<speed)            {                q.pop();                cnt++;            }        }        if(sign==2)        {            cnt+=overtake;            overtake=0;        }        if(sign==3)        {            scanf("%d",&limit);            q.push(limit);            while(q.empty()==false&&q.top()<speed)            {                q.pop();                cnt++;            }        }        if(sign==4)        {            overtake=0;        }        if(sign==5)        {            while(q.empty()==false)            {                q.pop();            }        }        if(sign==6)        {            overtake++;        }    }    cout<<cnt<<endl;}

T5:Fire in the City

题意:
分析过程:
给出题解:

T6:Guards In The Storehouse

题意:
分析过程:
给出题解:

T7:Shortest Path Problem?

题意:
分析过程:
给出题解:

蒻蒟的总结:

再一次补发昨天的微博,真的是好难啊,果然啊,几个月达到别人几年的效果,真的是很艰难的一段路啊。不过还是能够坚持下去的,明天就是短暂的周末了,也要好好利用起来,今天晚上继续理解KMP,DP,树和队列,明天凌晨在去做一场比赛,先把CF上的分刷出来再说,最后再把这几天没补的题目补好。好好利用每个周末,这些都是宝贵的时间,顺便休整一下。
继续贴出吴老师的话:学信息的人永不服输!!!

原创粉丝点击