20240809
赛时得分
| 题目 | A | B | C | D | E | F | G | H | 总分 | 排名 | 比例 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 满分 | 1000 | 1200 | 1500 | 1800 | 2000 | 2100 | 2200 | 2500 | 14300 | 168 | 100% |
| 得分 | 1000 | 1200 | 1500 | 1800 | 1000 | 420 | - | 0 | 6920 | 88 | 52.4% |
A. XXC 识字(1000/1000)
2 min 切题,\(\text{100%}\) 得分做法,string 和 ll 互换,翻转一下比较大小输出即可。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
string a,b;
ll c,d;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>a>>b;
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
c=stoi(a),d=stoi(b);
cout<<max(c,d);
return 0;
}
B. 小 C 的概率论(1200/1200)
\(\text{100%}\) 得分做法,写一个 cmp 满足一下题目中的优先级判断,开一个结构体分别记录一个值的值、出现次数、第一次出现的位置,用一个 set 维护即可。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=1001;
ll n,c,a[N],cnt;
set<ll> s;
struct lhm
{
ll val,tim,pos=2000;
}p[N];
bool cmp(lhm a,lhm b)
{
if(a.tim==b.tim) return a.pos<b.pos;
return a.tim>b.tim;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>c;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
if(s.find(a[i])==s.end())
{
s.insert(a[i]);
p[++cnt].val=a[i];
p[cnt].tim++;
p[cnt].pos=min(i,p[cnt].pos);
}
else
{
for(ll j=1;j<=cnt;j++)
{
if(p[j].val==a[i]) p[j].tim++;
}
}
}
sort(p+1,p+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
{
for(int j=1;j<=p[i].tim;j++) cout<<p[i].val<<" ";
}
return 0;
}
C. 调试代码(1500/1500)
\(\text{100%}\) 得分做法,首先根据题里给的代码直接模拟,然后多拿出来几个数预处理,是复杂度降到 log 级,最后前缀和维护答案,卡一卡就过去了。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=1e6+1;
ll n,k,q,x[N],l,r,sum[N],seq[N];
ll cnt,cnt2,cnt3,cnt4,cnt5,cnt6;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
scanf("%lld%lld",&n,&k);
for(int i=1;i<=k;i++)
{
scanf("%lld",&x[i]);
if(x[i]==1) cnt++;
else if(x[i]==2) cnt2++;
else if(x[i]==3) cnt3++;
else if(x[i]==4) cnt4++;
else if(x[i]==5) cnt5++;
else if(x[i]==6) cnt6++;
else
{
for(int j=0;j<n;j+=x[i]) seq[j]++;
}
}
for(int j=0;j<n;j++) seq[j]+=cnt;
for(int j=0;j<n;j+=2) seq[j]+=cnt2;
for(int j=0;j<n;j+=3) seq[j]+=cnt3;
for(int j=0;j<n;j+=4) seq[j]+=cnt4;
for(int j=0;j<n;j+=5) seq[j]+=cnt5;
for(int j=0;j<n;j+=6) seq[j]+=cnt6;
scanf("%lld",&q);
sum[0]=seq[0];
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+seq[i];
while(q--)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",sum[r]-sum[l-1]);
}
return 0;
}
D. 只是大牌(1800/1800)
\(\text{100%}\) 得分做法,考虑贪心,每次对方出牌,我们只出手牌中比他大的牌当中最小的那张,所以是二分答案题。那么我们用一个 set 维护手牌,直接 lower_bound 即可解决。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=5e4+1;
ll n,le[N],cnt,ans;
set<int> s,p;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>le[i];
s.insert(le[i]);
}
for(int i=1;i<=2*n;i++)
{
if(s.find(i)==s.end()) p.insert(i);
}
sort(le+1,le+n+1);
for(int i=1;i<=n;i++)
{
if(p.lower_bound(le[i])!=p.end())
{
ans++;
p.erase(p.lower_bound(le[i]));
}
}
cout<<ans;
return 0;
}
H. 行走的机器人(500/2500)
其实是数据水了才拿的分,那我不管,反正分是拿到了。
\(\text{20%}\) 得分做法,首先由于起始点和终止点都是充电桩,那么我们考虑把所有充电桩拉出来单独建一个图。那么我们 dij \(k\) 次原图,如果 \(i\) 和 \(j\) 两个点之间存在路径的话,我们就把这条边拿出来建到新图中,这条边的边权就是两个充电桩的最短路距离。
然后我们 dfs 遍历整张新图,从起点 \(a\) 走到终止 \(b\),每走一条边到达一个中间节点,我们就把这条边的边权和最大边权去一个 \(\max\),计算出对于这一条路径的充电量。对于所有路径,我们取一个 \(\min\) 值即可。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int N=3e5+1;
ll n,m,k,q,s,t,u,v,w,dis[N],a,b,ans=inf,bef;
vector<pair<ll,ll> > e[N],g[N];
bool vis[N];
void dijkstra(ll s,vector<pair<ll,ll> > e[])
{
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
priority_queue<pair<ll,ll> > q;
q.push({0,s});
while(!q.empty())
{
ll u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(auto i:e[u])
{
ll v=i.first,w=i.second;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
q.push({-dis[v],v});
}
}
}
return;
}
void dfs(ll u,ll w,ll len)
{
len=max(len,w);
if(u==b)
{
ans=min(ans,len);
return;
}
vis[u]=1;
for(auto i:g[u])
{
ll v=i.first,w=i.second;
if(!vis[v]) dfs(v,w,len);
}
vis[u]=0;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k>>q;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
e[u].push_back({v,w});
e[v].push_back({u,w});
}
for(int i=1;i<=k;i++)
{
dijkstra(i,e);
for(int j=1;j<=k;j++)
{
if(i==j) continue;
if(dis[j]!=inf)
{
g[i].push_back({j,dis[j]});
g[j].push_back({i,dis[j]});
}
}
}
while(q--)
{
cin>>a>>b;
memset(vis,0,sizeof(0));
ans=inf;
dfs(a,0,-1);
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号