2020年2月18日 林大OJ习题 set

2020年2月18日 set

set相当于一个自动排序+自动去重的数组,即插入时会自动排序,插入重复元素时不会变化。set的元素访问需要用到迭代器,其原理可以类比普通循环中的循环变量i。

林大OJ 743 明明的随机数-set

set的模版题,set的特点在排序和去重。

#include <bits/stdc++.h>

using namespace std;

set<int>a;

int main()
{
    int n,x;
    while(cin>>n){
        a.clear();
        for(int i=1;i<=n;i++){
            cin>>x;
            a.insert(x);
        }
        printf("%d\n",a.size());
        set<int>::iterator it;
        for(it=a.begin();it!=a.end();it++)
            it==a.begin()?printf("%d",*it):printf(" %d",*it);
        printf("\n");
    }
    return 0;
}

林大OJ 1684 第K小整数-set

仍然是模版题,看到“相同的数字只计算一次”就用set就对了。

#include <bits/stdc++.h>

using namespace std;

set<int>a;

int main()
{
    int n,x,k,cnt,flag;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>x;
        a.insert(x);
    }
    set<int>::iterator it;
    cnt=flag=0;
    for(it=a.begin();it!=a.end();it++){
        cnt++;
        if(cnt==k){
            printf("%d\n",*it);
            flag=1;
        }
    }
    if(flag==0) printf("NO RESULT\n");
    return 0;
}

林大OJ 2117 单词记忆-set-map

在set中查找元素用count函数更简单点,但只能知道有没有,这道题已经足够了。

#include <bits/stdc++.h>

using namespace std;

set<string>a;

int main()
{
    int n,f,flag;
    string x;
    cin>>n;
    a.clear();
    set<string>::iterator it;
    while(n--){
        cin>>f>>x;
        if(f==0) a.insert(x);
        if(f==1){
            flag=0;
            if(a.count(x)){
                printf("YES\n");
                flag=1;
            }
            if(flag==0) printf("NO\n");
        }
    }
    return 0;
}

林大OJ 1680 列车调度-SET

set中的数据存放是有顺序的。
这道题相当于找列车初始顺序中最长单调递减子序列的长度。换言之,如果新的一辆列车的序号大于目前所有轨道上末尾车的序号就要重开一条轨道用来调度。

#include <bits/stdc++.h>

using namespace std;

set<int>a;

int main()
{
    ios::sync_with_stdio(false);
    int n,num;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>num;
        if(!a.empty()&&*a.rbegin()>num)
            a.erase(*a.upper_bound(num));
        a.insert(num);
    }
    printf("%d\n",(int)a.size());
    return 0;
}

林大OJ 2119 相似的数集简单版-SET

利用count函数找到两个数集中相同元素的个数即可,因为要求相同元素两两不同,所以用set。

#include <bits/stdc++.h>

using namespace std;

set<int>a[51];

int main()
{
    ios::sync_with_stdio(false);
    int m,n,x,n1,n2,k;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>m;
        while(m--){
            cin>>x;
            a[i].insert(x);
        }
    }
    cin>>k;
    while(k--){
        cin>>n1>>n2;
        int same=0,dif=0;
        set<int>::iterator it;
        for(it=a[n1].begin();it!=a[n1].end();it++)
            if(a[n2].count(*it)) same++;
        dif=a[n1].size()+a[n2].size()-same;
        printf("%.2lf%%\n",1.0*same/(1.0*dif)*100.0);
    }
    return 0;
}

林大OJ 1679 NOIP 题海战-SET-1

题目很长,主要是要读懂题目每句话的意思。

#include <bits/stdc++.h>

using namespace std;

const int N=1e3+10;
int n,m,x,k,num,type;
set<int>s[N],quanji,ans;
set<int>::iterator it;

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>num;
        for(int j=1;j<=num;j++){
            cin>>x;
            s[i].insert(x);
        }
    }
    for(int i=1;i<=m;i++)
        quanji.insert(i);
    cin>>k;
    while(k--){
        cin>>type>>num;
        ans=quanji;
        if(type==0){
            for(int i=1;i<=num;i++){
                cin>>x;
                for(it=ans.begin();it!=ans.end();){
                    if(s[x].count(*it)) ans.erase(it++);
                    else it++;
                }
            }
        }
        else{
            for(int i=1;i<=num;i++){
                cin>>x;
                for(it=ans.begin();it!=ans.end();){
                    if(!s[x].count(*it)) ans.erase(it++);
                    else it++;
                }
            }
        }
        for(it=ans.begin();it!=ans.end();it++)
            printf("%d ",*it);
        printf("\n");
    }
    return 0;
}

林大OJ 1677 指数序列-set-map

这道题其实是昨天map的压轴题,因为又写着set,所以决定今天解决。这道题其实相当于又回到了二进制的计算上,大佬的题解
由于2x + 2x = 2x+1,对于一个非降序列,我们可以向上进位得到单调递增序列,如:

1 1 2 3 5——>2 2 3 5——>3 3 5——>4 5

由于2v-1 = 20 + 21 + 22 +……+ 2v-1,所以我们只需暴力找答案的二进制中0的个数。

#include <bits/stdc++.h>

using namespace std;

int n,x,s,mx;
set<int>ans;
map<int,int>vis;

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        vis[x]++;
        ans.insert(x);
        mx=max(mx,x);
    }
    set<int>::iterator it;
    for(it=ans.begin();it!=ans.end();it++){
        x=*it;
        int tmp=vis[x];
        vis[x]=tmp%2;
        if(vis[x]==0) s++;//统计被删除的数的个数
        int k=tmp/2;//将相同的两个数合并
        if(!vis[x+1]&&k!=0){
            ans.insert(x+1);//合并后的数大小+1
            mx=max(mx,x+1);//mx记录合并完成后数的最大值
        }
        vis[x+1]+=k;//合并后数的个数+k
    }
    printf("%d\n",mx+1-ans.size()+s);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值