czl蒻蒟的OI之路9

—>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 1000050
using 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 5000

int 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上的分刷出来再说,最后再把这几天没补的题目补好。好好利用每个周末,这些都是宝贵的时间,顺便休整一下。
继续贴出吴老师的话:学信息的人永不服输!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值