[补题|总结] 第一届河北工业大学程序设计竞赛校赛 C 标枪游戏

[补题|总结] 第一届河北工业大学程序设计竞赛校赛 C 标枪游戏_第1张图片

目录

  • 写在前头
  • 题意要求概括
  • 树状数组模板
    • 代码详解
  • 暴力做法
  • 非暴力(二分+思维)
  • 总结

写在前头

这题过了人挺多的,我从大根堆跑到二叉搜索树最后又打算二分,
结果都TLE(二分还没写)了,
给我搞的心态爆炸,结果题解竟然是树状数组,我真就哈哈哈哈哈

题意要求概括

就是给你一个数组,对于数组每次读入数,
你对当前这个数都要判断前面比他大的数的个数,和比他小的数的个数

树状数组模板

代码详解

```cpp
int getid(int x)
{
     
    return lower_bound(g.begin(),g.end(),x)-g.begin()+1;
     二分查找第一个比x大或等于的数 并返回该下标+1
}
int lowbit(int x)
{
     
    return x&(-x);
}

void update(int x)
{
     
    while(x<=n)
    {
     
        f[x]++;
        x+= lowbit(x);
    }
}
int query(int x)
{
     
    int sum=0;
    while(x)
    {
     
        sum+=f[x];
        x-= lowbit(x);
    }
    return sum;
}
cin>>n;
for(int i=1; i<=n; i++)
    scanf("%d",&a[i]),g.push_back(a[i]);

sort(g.begin(),g.end()); 
对原先的数组的值进行排序
for(int i=1; i<=n; i++)
    b[i]=getid(a[i]); 
 b[i] 存的是 当前这个有多少个<=他自己的
int ans1=0,ans2=0;
for(int i=1; i<=n; i++)
{
     
    if(i&1)
        ans1=ans1+1+query(b[i])-(query(n)-query(b[i]));
    else
        ans2=ans2+1+query(b[i])-(query(n)-query(b[i]));

    update(b[i]);
}

暴力做法

卧槽,原来暴力都可以
[补题|总结] 第一届河北工业大学程序设计竞赛校赛 C 标枪游戏_第2张图片
感谢我们的佬,教我计算这种时间复杂度,算出来正好是 5e9 又因为限制是2s稳过

int main()
{
     
    long long int num1=0,num2=0;
    int a,i,s[100005],sum,j;
    cin>>a;
    for(i=0; i<a; i++)
        cin>>s[i];

    for(i=0; i<a; i++)
    {
     
        sum=0;
        for(j=0; j<i; j++)
        {
     
            if(s[i]>=s[j]) 找比他大的
                sum++;
        }
        
        if(i%2==1)
            num1+=1+sum-(i-sum);
        else
            num2+=1+sum-(i-sum);
    }
    
    if(num1==num2)
        printf("hebei shuang king!");
    else if(num1>num2)
        printf("huaji is hebei king!");
    else
        printf("Calculus is hebei king!");
}

非暴力(二分+思维)

#include
using namespace std;
 
int main()
{
     
 
    long long n,a[100000],j=0,h=0;
    cin>>n;
    vector<long long>q;
    for(long long  i=0; i<n; i++)
    {
     
       long long num;
        cin>>a[i];
        long long  sum=upper_bound(q.begin(),q.end(),a[i])-q.begin();
        q.insert(q.begin()+sum,a[i]);
        这里加一个Sum真的太666666666%%%%%%%% 
        num=i-sum;
        if(i%2==0)
        j+=1+sum-num;
        else h+=1+sum-num;
    }
 
    if(j>h)
        cout<<"Calculus is hebei king!";
    else if(j<h)
        cout<<"huaji is hebei king!";
    else
        cout<<"hebei shuang king!";
    return 0;
}

总结

虽然说这次 我一直在纠结这题的数据结构虽然树状数组的确给我惊艳到了
但是 如果自己对这方面不怎么了解 更应该用思维去做题,可以说这次卡住了
没想到暴力做法也可以,这是我没想到的(时间复杂度还是不会计算)
同样地二分的这个**+sum**的思维可以说也不难
就是做少了

你可能感兴趣的:(认真&题解,某CPC)