20240823
赛时得分
| 题目 | A | B | C | D | 总分 | 排名 | 比例 |
|---|---|---|---|---|---|---|---|
| 满分 | 100 | 100 | 100 | 100 | 400 | 153 | 100% |
| 得分 | 60 | 50 | 30 | 20 | 160 | 91 | 59.5% |
A. 粉刷匠(60/100)
\(\text{30pts}\) 部分考虑直接 \(\mathcal{O}(nm)\) 直接枚举,开一个结构体存 set 进行维护即可。
\(\text{60pts}\) 有点乱搞成分在的。考虑把每个颜色左右边界存一下,但显然是可能不连续的。但显然 OI 是骗分游戏,精度上看误差不大。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
#define minn first
#define maxn second
using namespace std;
const int N=1e5+1;
ll n,m,a,b,c,cnt,ans=1,befl,befr,maxc=-1,maxx=-1;
map<ll,pair<ll,ll> > mp;
struct lhm
{
set<ll> s;
}col[N];
bool ok;
int main()
{
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
if(n<=100 and m<=100)
{
for(int i=1;i<=n;i++)
{
cin>>a>>b>>c;
for(int j=1;j<=m;j++)
{
if(j>=a and j<=b) col[j].s.insert(c);
else col[j].s.insert(0);
}
}
for(int i=1;i<=m;i++)
{
ll len=col[i].s.size();
maxx=max(maxx,len);
}
cout<<maxx;
return 0;
}
for(int i=1;i<=n;i++)
{
cin>>a>>b>>c;
if(i==1) befl=a,befr=b;
befl=max(befl,a),befr=min(befr,b);
maxc=max(maxc,c);
if(!mp[c].minn and !mp[c].maxn) mp[c].minn=a,mp[c].maxn=b;
else mp[c].minn=min(a,mp[c].minn),mp[c].maxn=max(b,mp[c].maxn);
}
for(int j=1;j<=m;j++)
{
if(j>=befl and j<=befr) cnt=0;
else cnt=1;
for(int i=1;i<=maxc;i++)
{
if(mp[i].minn==0) continue;
if(j<mp[i].minn or j>mp[i].maxn) continue;
cnt++;
}
ans=max(ans,cnt);
}
cout<<ans;
return 0;
}
B. 第 k 小(50/100)
\(\text{30%}\) 得分做法,直接暴力扔进一个 set 中。
\(\text{50%}\) 得分做法,考虑 \(k\leq n\) 的部分分,我们赌一波缩小范围,只扫到 \(\min(n/m,2\times\sqrt{k})\) 即可,这样在减小循环次数的同时也可以保证答案正确性。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=4e4+1;
ll n,m,k,a[N],b[N],tar;
multiset<ll> s;
int main()
{
freopen("kth.in","r",stdin);
freopen("kth.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k;
tar=((ll)sqrt(k))*2+1;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
if(n<=500 and m<=500)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) s.insert(a[i]+b[j]);
}
}
else
{
for(int i=1;i<=min(n,tar);i++)
{
for(int j=1;j<=min(m,tar);j++) s.insert(a[i]+b[j]);
}
}
auto it=s.begin();
advance(it,k-1);
cout<<*it;
return 0;
}
C. 比赛(30/100)
\(\text{30%}\) 得分做法,考虑直接 next_permutation 枚举全排列,然后直接加权概率即可。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
ll n,m,pos[5001];
struct lhm
{
ll num;
double val[5001];
}a[11];
double ans,cnt;
int main()
{
freopen("contest.in","r",stdin);
freopen("contest.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=max(n,m);i++) pos[i]=i;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) cin>>a[i].val[j];
}
if(n==m)
{
do
{
cnt=0;
for(int i=1;i<=n;i++) cnt+=a[i].val[pos[i]];
ans=max(ans,cnt);
}while(next_permutation(pos+1,pos+n+1));
printf("%.5lf",ans);
}
return 0;
}
D. 可爱宝宝拍照(20/100)
乱搞过的 \(20\) 分。没啥思路。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=1e5+1;
ll n,m,a,b,l,r,cnt;
struct lhm
{
ll a,b,len;
}f[N];
bool cmp(lhm x,lhm y)
{
if(x.len==y.len)
{
if(x.a==y.a) return x.b<y.b;
return x.a<y.a;
}
return x.len<y.len;
}
set<pair<ll,ll> > s;
int main()
{
freopen("photo.in","r",stdin);
freopen("photo.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>f[i].a>>f[i].b;
f[i].len=f[i].b-f[i].a+1;
}
sort(f+1,f+m+1,cmp);
s.insert({f[1].a,f[1].b});
for(int i=2;i<=m;i++)
{
cnt=0;
a=f[i].a,b=f[i].b;
for(auto j:s)
{
l=j.first,r=j.second;
if(a<=l and b>=r) cnt++;
}
if(cnt==0) s.insert({a,b});
if(cnt>1)
{
cout<<-1;
return 0;
}
}
cout<<s.size();
return 0;
}

浙公网安备 33010602011771号