CF练习记录~
主要聚焦在1200的题,不涉及什么算法同时也有一定难度。各种切入手段也不太一样,有很多都不熟悉,所以简单记录一下
B. Line Segments
本题是一个几何知识
- 如果包括起始连线在内的所有边在一起能形成一个多边形就可以
- 判断条件:除最长边之外所有边之和>=>=>=最长边
 
// Problem: CF2119B Line Segments
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF2119B
// Memory Limit: 250 MB
// Time Limit: 1500 ms
// Submission Time: 2025-10-15 20:00:10#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
double a[N];
int n,m;
string s;
void solve()
{int x,y,xx,yy;cin >> n;cin >> x >> y >> xx >> yy;vector<double> v(n);for(int i=0; i<n; i++) cin >> v[i];double k=sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y));v.pb(k);sort(all(v),greater<double>());double mx=v[0];double sum=0;for(int i=1; i<v.size(); i++) sum+=v[i];if(sum>=mx) cout << "Yes" << endl;else cout << "No" << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
D. Retaliation
题意比较简单,要么减iii要么减n−i+1n-i+1n−i+1
- 先选取v[1]和v[n],分别设操作1和2进行x和y次,得到方程
x+n∗y=v[1]n∗x+y=v[n] x+n*y=v[1]\\ n*x+y=v[n] x+n∗y=v[1]n∗x+y=v[n]
- 要保证一定要有非负整数解,否则不行
- 到了这里就只有一组解了,将这组解代入到所有的元素中,如果都成立就可以
// Problem: Retaliation
// Contest: Virtual Judge - CodeForces
// URL: https://vjudge.net/problem/CodeForces-2117D#author=DeepSeek_zh
// Memory Limit: 1024 MB
// Time Limit: 1000 ms
// Submission Time: 2025-10-29 14:12:41void solve()
{cin >> n;vector<int> v(n+1);for(int i=1; i<=n; i++) cin >> v[i];int st=v[1],f=v[n];int mu=n*st-f;if(mu%(n*n-1)!=0){cout << "NO" << endl;return ;}int y=mu/(n*n-1);int x=st-n*y;if(x<0||y<0){cout << "NO" << endl;return ;}for(int i=1; i<=n; i++){if(x*i+y*(n-i+1)!=v[i]){cout << "NO" << endl;return ;}}cout << "YES" << endl;
}
C. Cool Partition
这个题想了一会沾了点边,但是还是没想到这么好的实现方法
- 由于后面的集合一定都包含之前的,所以可以设置两个set分别是总的和当前的
- 如果当前集合和总集合相同那么就算一个,清空当前集合并重新计算当前集合
// Problem: C. Cool Partition
// Contest: Codeforces - Codeforces Round 1029 (Div. 3)
// URL: https://codeforces.com/problemset/problem/2117/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Submission Time: 2025-10-29 15:52:44#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
int a[N];
int n,m;
string s;
void solve()
{cin >> n;set<int> al,cu;int ans=0;for(int i=0; i<n; i++){int x;cin >> x;al.insert(x);cu.insert(x);if(al.size()==cu.size()){ans++;cu.clear();}}cout << ans << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
B.Good Start
乍一看这个题的通过人数明显少于其他题,但是它其实一点都不难,只是有一点点细
分为这几种情况:

- 前一种是横或竖本来就留有狭长空隙,需要空隙是长或宽的倍数才行
- 后一种是本来没有空隙,经过填充之后出来了空隙,同样需要长或宽是空隙的倍数
// Problem: Good Start
// Contest: Virtual Judge - CodeForces
// URL: https://vjudge.net/problem/CodeForces-2113B#author=DeepSeek_zh
// Memory Limit: 1024 MB
// Time Limit: 1000 ms
// Submission Time: 2025-10-30 14:26:05#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
// int a[N];
int n,m;
string s;
void solve()
{int w,h,a,b;cin >> w >> h >> a >> b;int x1,y1,x2,y2;cin >> x1 >> y1 >> x2 >> y2;int mi=min(a,b);//填充的短边int mx=max(a,b);if(min(y1,y2)+b>max(y1,y2)){int gap=max(x1,x2)-(min(x1,x2)+a);if(gap%a==0) cout << "Yes" << endl;else cout << "No" << endl;}else if(min(x1,x2)+a>max(x1,x2)){int gap=max(y1,y2)-(min(y1,y2)+b);if(gap%b==0) cout << "Yes" << endl;else cout << "No" << endl;}else if((max(y1,y2)-(min(y1,y2)+b))%b==0||(max(x1,x2)-(min(x1,x2)+a))%a==0) cout << "Yes" << endl;else cout << "No" << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
B. Slice to Survive
- 只有第一步(a,b)不是最优的地方,需要分四种情况分别进行模拟
- 设此时的长和宽分别为x和yx和yx和y,每一次都会跑到((x+1)/2,(y+1)/2)((x+1)/2,(y+1)/2)((x+1)/2,(y+1)/2)这个地方,这样才能更慢被砍掉
- 对砍掉的过程进行模拟,取四种情况中的最小值就行了
// Problem: Slice to Survive
// Contest: Virtual Judge - CodeForces
// URL: https://vjudge.net/problem/CodeForces-2109B#author=DeepSeek_zh
// Memory Limit: 1024 MB
// Time Limit: 1000 ms
// Submission Time: 2025-10-30 15:17:11#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
// int a[N];
int n,m;
string s;
void solve()
{int a,b;cin >> n >> m >> a >> b;vector<pii> v={{n-a+1,m},{n,m-b+1},{a,m},{n,b}};int ans=INF;for(auto [x,y]:v){int num=0;while(x>1){num++;x=(x+1)/2;}while(y>1){num++;y=(y+1)/2;}ans=min(ans,num);}cout << ans+1 << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
E. Boneca Ambalabu
这又是一道位运算的好题,之前感觉位运算非常绕很难,现在感觉有点意思,无非就是那些操作。现在虽然还是不熟练但是起码能悟到一些
- 由于是做加法,各个数字之间都是独立的,所以我们可以先将其各位为1的数量统计一下
- 遍历v的所有数,如果此位为1,由于异或的性质,需要加上此位为0的数量*当位的数(1<<j)
- 就这样的过程将v全部遍历一遍取最大值就行了
// Problem: E. Boneca Ambalabu
// Contest: Codeforces - Codeforces Round 1017 (Div. 4)
// URL: https://codeforces.com/problemset/problem/2094/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Submission Time: 2025-10-30 18:14:59#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
int n,m;
string s;
void solve()
{int cnt[50]={0};cin >> n;vector<int> v(n);for(int i=0; i<n; i++){cin >> v[i];for(int j=0; j<=32; j++)if((v[i]>>j)&1) cnt[j]++;}int ans=-INF;for(int i=0; i<n; i++){int num=0;for(int j=0; j<=32; j++){if((v[i]>>j)&1) num+=(n-cnt[j])*(1LL<<j);else num+=cnt[j]*(1LL<<j);}ans=max(ans,num);}cout << ans << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
C. Asuna and the Mosquitoes
这道题有点意思,开始感觉非常的绕,还好冷静思考了一下得到规律
- 如果没有奇数或偶数那么无法进行操作,直接输出最大值就行了
- 尽量让最后一个数是奇数,这样的话前面的偶数可以直接加到上面而奇偶性不会变,如果是奇数只能加n-1,使得可以加其他数
- 如果最后一个是偶数的话就让它变成奇数然后就变成了👆的情况,后来发现这个也不用特殊处理,答案一样
// Problem: Asuna and the Mosquitoes
// Contest: Virtual Judge - CodeForces
// URL: https://vjudge.net/problem/CodeForces-2092C#author=DeepSeek_zh
// Memory Limit: 1024 MB
// Time Limit: 1000 ms
// Submission Time: 2025-10-30 19:06:02#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
int a[N];
int n,m;
string s;
void solve()
{cin >> n;//如果前n-1的奇数多就变偶,不然还是奇vector<int> v(n);int ji=0,ou=0;int sum=0;int mx=-INF;for(int i=0; i<n; i++){cin >> v[i];sum+=v[i];if(v[i]%2) ji++;else ou++;mx=max(mx,v[i]);}if(!ji||!ou){cout << mx << endl;return ;}cout << sum-ji+1 << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
D. Place of the Olympiad
从人数也可以看出来这题简单一点,可能是因为涉及到了二分的原因
- 每一排都是独立的,只针对坐人最多的那一排进行讨论
- 直接一个二分答案找一下符合条件的最小值就行了
// Problem: Place of the Olympiad
// Contest: Virtual Judge - CodeForces
// URL: https://vjudge.net/problem/CodeForces-2091D#author=DeepSeek_zh
// Memory Limit: 1024 MB
// Time Limit: 1000 ms
// Submission Time: 2025-10-30 19:42:11#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fi first
#define se second 
#define endl '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
const int INF = 1e18;
const int N = 1e6+5;
int a[N];
int n,m,k,num;
string s;
bool check(int x)
{int xx=m/(x+1)*x;int val=xx+m-(m/(x+1)*(x+1));if(val>=num) return 1;return 0;
}
void solve()
{cin >> n >> m >> k;int ans;num=k/n;if(k%n) num++;int l=1,r=(int)1e9+5;while(l<=r){int mid=l+r>>1;if(check(mid)) r=mid-1,ans=mid;else l=mid+1;}cout << ans << endl;
}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T=1;cin >> T;while(T--) solve();return 0;
}
总结
对现在来说还是比较有难度的,还是思维为主,套路各式各样,写起来也不算顺利。
