微博转发
#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;
}