t1
两个链表找交集
用map或者hash记录其中一个就行。
map<ll,bool>mp;
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
mp[x]++;
}
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(mp[x])
cout<<x<<" ";
}
cout<<endl;
}
signed main()
{
int t=1;
while(t--)
solve();
return 0;
}
t2
给定n个人和m个人的小团体,消息从0开始传播,问传播到多少人
并查集
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll N=1e5+5;
const ll INF=1e17;
ll parent[N];
struct node
{
ll next;
ll to;
}e[N*2];
ll head[N];
ll n;
bool vis[N];
ll tol;
void init() {
tol = 0;
for (int i = 0; i <= n; ++i) {
head[i] = -1;
vis[i] = false;
}
}
inline void add(ll y, ll x) {
e[tol].to = x;
e[tol].next = head[y];
head[y] = tol++;
}
ll ans=0;
void dfs(ll u)
{
for (int i = head[u]; i !=-1 ; i=e[i].next) {
ll v=e[i].to;
if(!vis[v])
{
vis[v]=true;
ans++;
dfs(v);
}
}
}
ll a[N];
int main()
{
ll m,len,x;
while (scanf("%lld %lld",&n,&m)!=EOF)
{
init();
for (int i = 0; i <m ; ++i) {
scanf("%lld",&len);
scanf("%lld",&a[0]);
for (int j = 1; j <len ; ++j) {
scanf("%lld",&a[j]);
add(a[j],a[j-1]);
add(a[j-1],a[j]);
}
}
ans=1;
vis[0]=true;
dfs(0);
printf("%lld\n",ans);
}
return 0;
}
t3
题意:给n个字符串,然后统计出,出现次数前k多和前k少的(出现次数不能为0)的字符串
输入:
第一行n和k
下面n行,每行一个字符串
解题:用map存一下字符串出现次数,然后都拿到结构体里面,然后结构体排序,注意当次数一样的时候,要按字典序排序
具体看代码
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
using namespace std;
const int N = 3e5 + 10;
string s[N];
map<string , int>ans;
struct degfe
{
int cnt;
string s;
bool operator < (const degfe & a) const
{
if(cnt==a.cnt)
return s<a.s;
return cnt < a.cnt;
}
} e1[N];
bool cans(degfe a , degfe b)
{
if(a.cnt==b.cnt)
return a.s<b.s;
return a.cnt > b.cnt;
}
signed main()
{
int n , k;
cin >> n >> k;
for(int i=1; i<=n; i++)
{
string str;
cin >> str;
ans[str] ++ ;
}
int cnt = 0;
for(auto i : ans)
e1[++ cnt] = degfe {i.se , i.fi};
sort(e1 + 1 , e1 + 1 + cnt , cans);
for(int i=1; i<=k; i++)
{
cout << e1[i].s << " " << e1[i].cnt << endl;
}
sort(e1 + 1 , e1 + 1 + cnt);
for(int i=1; i<=k; i++)
{
cout << e1[i].s << " " << e1[i].cnt << endl;
}
return 0;
}
T4
题意:给定一个偶数大小的数组,假设为2X大小,问每次删除一个数后,中位数是哪个。
思路:显然,因为只删除一个数,所以中位数的波动范围也是1,我们以X为分界线,如果删除的数<=a[X],那么中位数为a[X+1],否则中位数为a[X];所以只需要排序得到每个数的排名即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e5 + 10;
string s[N];
map<string ,int>mp;
struct node
{
int cnt;
string s;
bool operator < (const node & a) const
{
return cnt < a.cnt;
}
} a[N];
bool cmp(node a , node b)
{
return a.cnt > b.cnt;
}
signed main()
{
int n , k;
cin >> n >> k;
for(int i=1; i<=n; i++)
{
string s;
cin >> s;
mp[s] ++ ;
}
int cnt = 0;
for(auto i : mp)
a[++ cnt] = node {i.second , i.first};
sort(a + 1 , a + 1 + cnt , cmp);
for(int i=1; i<=k; i++)
cout << a[i].s << " " << a[i].cnt << '\n';
sort(a + 1 , a + 1 + cnt);
for(int i=1; i<=k; i++)
cout << a[i].s << " " << a[i].cnt << '\n';
return 0;
}