zoukankan      html  css  js  c++  java
  • cf Sonya and Robots

    题目网址点击打开链接

        题目意思是给你一个序列,要从左边数起第一个a的位置要在从右边数起第一个b的位置的前面,让你求(a,b)这样的一对数的种数是多少。

        序列里的每个数都可以和他后面的全部数组成(a,b),但是有重复。重复分2种,一种是(2,3,3)这种情况,可以组成2个(2,3),但是有重复就只算1种,要避免这种情况就要维护每一个数字后面数的种类。一种是(3,3,2)这种情况,可以组成(3,3)和(3,2)和(3,3)但是有重复只算2种,要避免这种情况就要用vis数组,假如一个数已经做过一次a了,那么下次就不能做a了。做法就是对这个序列进行桶排序,但并不是获取这个序列的升序或减序序列,是要记录下这个序列的每种数的个数,以及这个序列的数的种数,另外还设了一个标记数组标记哪些数字做过a了。

        从头到尾扫一遍,用cnt维护该数字后面的数的种类,然后cnt即是该数字可以和后面的数组成(a,b)的种数,然后判断一下该数字是否做过a了,做过了的话就跳过该数字,若是没做过就ans+=cnt,然后给该数组标记。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    int n,a[maxn],t[maxn],vis[maxn];//t数组表示桶数组
    int main()
    {
        long long cnt=0,ans=0;
        cin>>n;
        for(int i=0;i<n;i++)//桶排序,在桶排序的过程中统计序列中有多少种数
        {
            cin>>a[i];
            if(t[a[i]]==0)
            {
                cnt++;
            }
            t[a[i]]++;
        }
        for(int i=0;i<n;i++)
        {
            t[a[i]]--;
            if(t[a[i]]==0)  cnt--;
            if(!vis[a[i]])
            {
                ans+=cnt;
                vis[a[i]]=1;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    


  • 相关阅读:
    linux usb驱动——OTG数据线与普通数据线区别
    linux内核——设置打印信息
    loop设备及losetup命令介绍[转]
    Linux设备(dev)介绍
    开启windows的 admin+开启tel+电源+远程功能
    JL MTK 安防网关的 wifi 吞吐测试
    如何设置默认以管理员权限运行cmd
    docsis cm 上线过程(bigwhite)
    将win7 设置为 NTP服务器
    tshark的抓包和解析
  • 原文地址:https://www.cnblogs.com/eason9906/p/11755102.html
Copyright © 2011-2022 走看看