SMU winter 2025 Personal Round 1
第一场个人赛。
过题数3/7,补题1。
https://codeforces.com/group/L9GOcnr1dm/contest/582356
A. Level Statistics

输入T组。
每组输入一个n,表示观看时刻数。
输入一行两个整数,表示玩该关卡的次数和通关次数。
如果输入的数据游玩次数的增长小于通关次数的增长,游玩总次数随时间下降或通关总次数随时间下降,通关次数大于游玩次数。那么就输出NO,否则输出YES。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod9 = 998244353;
const int mod1 = 1e9 + 7;
#define x first
#define y second
// 二分暴龍龍
struct xx{
int p,c;
};
void miaojiachun()
{
int n;
cin>>n;
vector<xx>a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i].p>>a[i].c;
}
int flag=0;
for(int i=1;i<=n;i++){
if(a[i].p-a[i-1].p<a[i].c-a[i-1].c){
flag=1;
}
if(a[i].p<a[i-1].p or a[i].c<a[i-1].c){
flag=1;
}
if(a[i].c>a[i].p){
flag=1;
}
}
if(flag){
cout<<"NO"<<endl;
}else{
cout<<"YES"<<endl;
}
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int ING = 1;
cin >> ING;
while (ING--)
{
miaojiachun();
}
return 0;
}
B.Middle Class


n个人要变成富人,成为富人的最低标准是拥有x元,我们可以先把现有富人多余的钱拿走,然后按金钱数从大到小的顺序分配给穷人。这样可以保证人数最多。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod9 = 998244353;
const int mod1 = 1e9 + 7;
#define x first
#define y second
// 二分暴龍龍
void miaojiachun()
{
int n,x;
cin>>n>>x;
vector<int>a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a.begin()+1,a.end());
if(a[1]>=x){
cout<<n<<endl;
return;
}
int sum=0;
for(int i=1;i<=n;i++){
if(a[i]>x){
sum+=a[i]-x;
a[i]=x;
}
}
for(int i=n;i>=1;i--){
if(a[i]<x and sum>=x-a[i]){
sum-=x-a[i];
a[i]=x;
}
}
int num=0;
for(int i=1;i<=n;i++){
if(a[i]>=x){
num++;
}
}
cout<<num<<endl;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int ING = 1;
cin >> ING;
while (ING--)
{
miaojiachun();
}
return 0;
}
C.Circle of Monsters
只需要确定一开始攻击的怪就行。因为把第一个怪打死后,最优策略为继续攻击被炸伤的怪,因为被炸伤的怪没法再被炸一次了,只能消耗子弹攻击它,而如果选择其他满血的怪打,那个怪本可以先被炸再打的,这样无疑浪费了子弹。因此只需要先处理出每个怪的血量减去爆炸所受伤害的前缀和,枚举一下一开始打哪个怪,答案取最小即可。注意成环的话要复制一遍数组。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod9 = 998244353;
const int mod1 = 1e9 + 7;
#define x first
#define y second
// 二分暴龍龍
void miaojiachun()
{
int n;
cin>>n;
vector<PII>a(n+2);
for(int i=1;i<=n;i++){
cin>>a[i].x>>a[i].y;
}
a[n+1]=a[1];
int sum=0;
int min1=inf/2;
for(int i=2;i<=n+1;i++){
int yy=max(a[i].x-a[i-1].y,0ll);//每个人必须要耗费的子弹数
sum+=yy;
min1=min(min1,a[i].x-yy);//找到需要耗费子弹数最少的一个人做开始
}
cout<<sum+min1<<endl;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int ING = 1;
cin >> ING;
while (ING--)
{
miaojiachun();
}
return 0;
}
D. Minimum Euler Cycle

给你一个n个结点的完全图,找出最小字典序的欧拉回路遍历的结点,输出其中一段。
就是先从小的结点开始,向尽量小的结点走,多枚举一下就可以找出规律。

两个两个看,以1开头的有n - 1个,以二开头的有n - 2个,以此类推。 这样就可以快速算出 l 所在位置开头的结点,然后枚举输出。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 7;
const int inf = LLONG_MAX / 10;
const int mod9 = 998244353;
const int mod1 = 1e9 + 7;
#define x first
#define y second
// 二分暴龍龍
int d[N];
void miaojiachun()
{
int n,l,r;
cin>>n>>l>>r;
int now=0;
for(int i=1;i<n;i++){
d[i]=now+(n-i)*2;
now=d[i];
}
d[n]=now+1;
for(int i=l;i<=r;i++){
int p=lower_bound(d+1,d+n+1,i)-d;
if(i==d[n]){
cout<<1<<" ";
break;
}if(i&1){
cout<<p<<" ";
}else{
int t=i-d[p-1];
cout<<t/2+p<<" ";
}
}
cout<<endl;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int ING = 1;
cin >> ING;
while (ING--)
{
miaojiachun();
}
return 0;
}

浙公网安备 33010602011771号