[算法学习记录] ABC402 A-D题解
A - CBC
遍历一下,看有多少个大写字母就行。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void solve()
{
string S;cin >> S;
for(int i = 0;i<S.size();i++) if(S[i]>='A'&&S[i]<='Z')cout << S[i];
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
while(_--)solve();
return 0;
}
B - Restaurant Queue
用栈就能解决,操作1就入栈,操作2就输出栈顶元素并出栈。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
queue<int> q;
void op1()
{
int x;cin >> x;
q.push(x);
}
void op2()
{
int x = q.front();q.pop();
cout << x <<"\n";
}
void solve()
{
int q;cin >> q;
while(q--)
{
int op;cin >> op;
if(op==1)op1();
else op2();
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
while(_--)solve();
return 0;
}
C - Dislike Foods
本题数据量较大,如果我们用邻接表把每道菜的配料存在一起,暴力匹配肯定会超时;我们尝试反过来存每个配料存在于那几个菜中,接下来我们只要遍历每天适应的配料,就能轻松解决。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 3e5+5;
vector<int> g[N];
//存储每种配料存在于哪几道菜中
int b[N],flag[N];
//flag为每天适应的配料,flag,为每道菜的配料数量
bool vis[N];
//一道菜的每种配料都适应了,就标记为true
void solve()
{
int n,m,count = 0;cin >> n >> m;
for(int i = 1;i<=m;i++)
{
int k;cin >> k;
flag[i] = k;
while(k--)
{
int a;cin >> a;
g[a].push_back(i);
}
}
for(int i = 1;i<=n;i++)cin >> b[i];
for(int i = 1;i<=n;i++)
{
for(auto &x : g[b[i]])
{
flag[x]--;
if(!flag[x]&&!vis[x])
{
count++;
vis[x] = true;
}
}
cout << count <<"\n";
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
while(_--)solve();
return 0;
}
D - Line Crossing
容易发现每天直线的每两个点的坐标之和只要相等(这里将它定义为斜率),这两条直线就平行。
我们可以先计算所有直线对的数量,在计算平行的直线对数量,总的减去平行的就是相交的。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll,ll>;
const int N = 1e6+5,M = 3e5+5;
pii g[N];
ll k[N];
//存储斜率
map<ll,ll>mp;
void solve()
{
ll n,m;cin >> n >> m;
for(int i = 1;i<=m;i++)
{
ll a,b;cin >> a >> b;
g[i] = {a,b};
}
for(int i = 1;i<=m;i++)
{
k[i] = (g[i].first + g[i].second) % n;
if(mp.count(k[i]) == 0) mp[k[i]] = 1;
else mp[k[i]]++;
}
//用map存储每种斜率的直线数量
ll ans = m * (m - 1) / 2;
//先计算总的
for(auto &x : mp) ans -= 1ll * x.second * (x.second - 1) / 2;
//计算相交的直线对数量(组合数C(n,2))
cout << ans<<"\n";
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
while(_--)solve();
return 0;