齐大第十一届校赛第三题
时间限制:1000ms 内存限制:65535KB
题目描述:
Cola 作为一位手搓单晶硅的硬核大佬,自然通晓许多魔法。
比如,他最近参加了生物竞赛,学习了┌ 神符 · 基因匹配┘,他可以对两种生物的基因进行分析匹配。老师为了考验 Cola ,便给他 2n 种不同生物的基因,要 Cola 分出 n 组进行分析匹配,每组一定由2种基因组成(基因不能重复使用)。这可把 Cola 难住了:“这已经超过了碳基生物的整活范畴了!”
原来,这 2∗n 种基因中,包含以 A 元素为基础的生物,以 B 元素为基础的生物和以 C 元素为基础的生物,它们还各自包含一个各自特征值 ai (1≤i≤2n)。
进行分析匹配时,如果这两种生物的基因以同一种元素为有机物质基础,对于 Cola 来说需要的计算难度可以忽略不记 ;
但是如果这两种生物的基因不以同一种元素为有机物质基础,那 Cola 计算他们的难度为它们特征值差的绝对值。
现在请您输出 Cola 进行这 n 组匹配计算难度总和的最小值。
输入格式:
第一行一个整数 n ,代表 Cola 要进行匹配的组数。
接下来的 2n 行,每行一个整数 ai 和一个字符 ci 。分别代表特征值和该生物有机物质基础的元素。其中 1≤n≤105 , 1≤ai≤1015 , ci∈{'A','B','C'} 。
输出格式:
一个整数,代表最小的计算难度总和。
代码实现:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
vector<ll> a[4];
ll n,t,ans,id[4]={0,1,2,3};
char ch;
ll mabs(ll num)
{
return num>=0?num:-num;
}
ll slove(ll x,ll y)
{
int l1=a[x].size(),l2=a[y].size();
if(x>y)
{
swap(x,y);
swap(l1,l2);
}
ll res=mabs(a[y].back()-a[x].front());
for(int i=0;i<l1;i++)
{
int pos=upper_bound(a[y].begin(),a[y].end(),a[x][i])-a[y].begin();
if(pos<l2)
res=min(res,mabs(a[x][i]-a[y][pos]));
if(pos!=0)
res=min(res,mabs(a[x][i]-a[y][pos-1]));
}
return res;
}
bool cmp(ll x,ll y)
{
return (a[x].size()%2) > (a[y].size()%2);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
n*=2;
for(int i=1;i<=n;i++)
{
cin>>t>>ch;
a[ch-'A'+1].push_back(t);
}
for(int i=1;i<=3;i++)
sort(a[i].begin(),a[i].end());
sort(id+1,id+4,cmp);
if(a[id[1]].size()%2!=0)
{
ans=slove(id[1],id[2]);
if(a[id[3]].size())
ans=min(ans,slove(id[1],id[3])+slove(id[2],id[3]));
}
cout<<ans<<endl;
return 0;
}
本题为本次比赛防ak题,孩子不会。。。就先把答案放这啦