acwing

文章探讨了哈希表、最长严格递增子序列、使用unordered_set求不同元素个数、差分与前缀和计算、优先队列在牛用餐问题中的应用、并查集连通块的合并与查询,以及解决特定字符矩阵中连通段的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

微博转发


#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=1010,M=100010;
int h[N],ne[M],e[M],idx;
int L,s;
bool st[N];

void add(int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
int bfs(int start)

{
    memset(st,0,sizeof st);
    st[start]=true;
    queue<int> q;
    q.push(start);
    int res=0;
    for(int i=1;i<=L;i++)
    {
        int sz=q.size();
        while(sz--)
        {
            int t=q.front();
            q.pop();
           
            for(int j=h[t];j!=-1;j=ne[j])
            {
                int x=e[j];  //
                if(!st[x])  //不是j
                {
                    st[x]=true;
                    q.push(x);
                    res++;
                }
            }
        }
    }
    return res;
}

int main()
{
      memset(h,-1,sizeof h); //*******
    cin>>s>>L;
    for(int i=1;i<=s;i++)
    {
        int n;
        cin>>n;
        while(n--)
        {
            int x;cin>>x;
            add(x,i);
        }
    }
    int k;
    cin>>k;
    while(k--)
    {
        int m;
        cin>>m;
        cout<<bfs(m)<<endl;
    }
}

哈希表

最长严格递增子序列

#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_set>//*********头文件
using namespace std;
/*1≤ai≤109
哈希表    unordered_map值可重复  unordered_set值不可重复*/

//即找不同元素 的 个数



int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
    cin>>n;
    unordered_set<int> hash;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        hash.insert(x);//insert
        
    }
    cout<<hash.size()<<endl;
    }
    return 0;
}

差分,前缀和

合格数

/*包含  l~r内 每个数 都+1(差分)  b[i]>=k
+了几就是被几个区间包含(求原数组)
求a~b内至少,,,k,,,:前缀和
s[l]-s[i-1]   满足->s[i]++*/

#include<iostream>
using namespace std;
const int N=200010;
int s[N],b[N];
int n,k,q;
int main()
{
    cin>>n>>k>>q;
    while(n--)
    {
        int l,r;
        cin>>l>>r;
        b[l]++,b[r+1]--;//差分数组
    }
    for(int i=1;i<N;i++)
    {
        b[i]+=b[i-1];//原数组
    }
    for(int i=1;i<N;i++)
    {
        s[i]=s[i-1]; //前缀和数组
        if(b[i]>=k) s[i]++;
    }
    while(q--)
    {
        int l,r;
        cin>>l>>r;
        cout<<s[r]-s[l-1]<<endl;
    }
    return 0;
}

数学

 删除

/*被8整除:后三位被8整除
枚举(后)三位即可*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    string s;
    cin>>s;
    s="00"+s;
    for(int i=0;i<s.size();i++)
    {
        for(int j=i+1;j<s.size();j++)
        {
            for(int k=j+1;k<s.size();k++)
            {
                int x=(s[i]-'0')*100+(s[j]-'0')*10+s[k]-'0';
                if(x%8==0) 
                {
                    printf("YES\n%d\n",x);
                    return 0;
                }
            }
        }
    }
    cout<<"NO"<<endl;
    return 0;
}

优先队列

奶牛用餐

/*座位 :每次用最早用完的 最小值 添加值
优先队列:堆
每次空闲时刻

n=5e10 ,k=1 ,t=5e10
最后牛在5e10*5e10吃 超int*/


#include <iostream>
#include <algorithm>
#include <queue>
#include<vector>
using namespace std;

typedef long long LL;
priority_queue<LL, vector<LL>, greater<LL>> q;

int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=0;i<k;i++) q.push(0); //k个座位 空闲时刻初始都为0
  
    while(n--)
    {
        int start,time;
        cin>>start>>time;
        //while(q.size())不要
        //{
            auto t=q.top();
            q.pop();
            
            LL end=max((LL)start,t)+time;
            
            q.push(end);
       // }
        cout<<end<<endl;
    }
    return 0;
}

并查集 连通块


using namespace std;

const int N = 100010;

int n, m;
int p[N], cnt[N];

int find(int x)
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}


int main()
{
    cin >> n >> m;

    for (int i = 1; i <= n; i ++ )
    {
        p[i] = i;
        cnt[i] = 1;
    }

    while (m -- )
    {
        string op;
        int a, b;
        cin >> op;
         if (op == "C")
        {
            cin >> a >> b;
            a = find(a), b = find(b);
            if (a != b)
            {
                p[a] = b;
                cnt[b] += cnt[a];
            }
        }
        else if (op == "Q1")
        {
            cin >> a >> b;
            if (find(a) == find(b)) puts("Yes");
            else puts("No");
        }
         else
        {
            cin >> a;
            cout << cnt[find(a)] << endl;
        }
    }
    /*
    int sum=0;
    
  for(int i=1;i<=n;i++) if(find(i)==i) sum++;  //此 步 sum 算连通块数量*******
    
    cout<<sum<<endl;*/
    return 0;
}

思维

残垣断壁


//最下一行联通段数量

//左边是. 或者空  就是每一段的第一个B *****
#include<iostream>
using namespace std;
char a[110][110];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        cin>>a[i][j];
    }
    
    int sum=0;
    for(int i=0;i<m;i++)
    {
        if(a[n-1][i]=='B')  //*********** 首先得是B  有....情况
        if(i==0 || a[n-1][i-1]=='.') sum++; //***
    }
    cout<<sum;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值