- 现在需要在坐标平面上以某一点 C 为圆心画一个圆,且该圆心必须位于坐标轴上。
请你找到一个最小的半径r,使得这圆能够覆盖不少于[n/2]个给定点,并输出这个最小半径。
【名词解释】
坐标轴:包含x轴和y轴。x 轴表示形如(x,0)的所有点;y轴表示形如(0,y)的所有点。
覆盖:若点 P 到圆心 c 的欧氏距离不超过圆的半径,则称该圆覆盖点 P。
#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int>> points;
int n;
bool check(double mid){
auto get = [&](int mode){
vector<pair<double,int>> ans;
for(auto p:points){
if(mode == 0){
if(fabs(p.second)>mid) continue;
double d = sqrt(mid*mid - p.second*p.second);
ans.emplace_back(p.first - d, 1);
ans.emplace_back(p.first + d, -1);
}else{
if(fabs(p.first)>mid) continue;
double d = sqrt(mid*mid - p.first*p.first);
ans.emplace_back(p.second -d,1);
ans.emplace_back(p.second + d,-1);
}
}
sort(ans.begin(),ans.end(),[](const pair<double,int>& p1,const pair<double,int>& p2){
if(p1.first == p2.first) return p1.second < p2.second;
else return p1.first<p2.first;
});
int count =0;
for(auto p:ans){
count += p.second;
if(count>=(n+1)/2) return true;
}
return false;
};
return get(0)||get(1);
}
int main(){
cin>>n;
points.resize(n);
for(int i=0;i<n;i++){
cin>>points[i].first>>points[i].second;
}
double lo = 0;double hi = 2e5;
for(int i=0;i<50;i++){
double mid = (lo + hi)/2;
if(check(mid)) hi = mid;
else lo = mid;
}
cout<<fixed<<setprecision(6)<<hi<<endl;
return 0;
}
-
给出一个长度为 n 的序列 a1,a2,a3...an,按以下规则输出序列的中位数:
-
若序列长度为奇数,中位数是升序排序后中间的数字。
-
若序列长度为偶数:
- 升序排序后,中间两数字 x=y 时,输出任意一个;
- 升序排序后,中间两数字 x=y 时,输出 min(x,y)。
-
输出中位数 midx 后,该数从序列消失,重复步骤直至序列元素全部输出。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
vector<int> nums(n);for(int i=0;i<n;i++)cin>>nums[i];
sort(nums.begin(),nums.end());
vector<int> ans;
for(int i = (n-1)/2;i>=0;i--){
ans.push_back(nums[i]);
if(2*i == n-1) continue;
ans.push_back(nums[n-1-i]);
}
for(int i=0;i<n;i++){
if(i)cout<<" ";
cout<<ans[i];
}
return 0;
}
-
任何一个数 n 都可以拆成若干项不同的、由 2 的次幂和 3 的次幂相乘之和,即 n=2a1×3b1+2a2×3b2+⋯+2am×3bm 且 2ai3bi=2aj3bj (1≤i<j≤m) 。给定整数 n,找到长度为 m 的序列 a1,a2,⋯,am 和 b1,b2,⋯,bm 满足方程,并按由大到小顺序依次输出。
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
vector<int> ans;
while(n){
int sum=0;
int factor=1;
while(factor2<=n){
factor=factor2;
}
ans.push_back(factor);
n -= factor;
}
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++){
if(i)cout<<" ";
cout<<ans[i];
}
cout<<endl;
}
return 0;
} -
小强最近在研究围棋,他希望有一个程序能告诉他一步之内,有哪些位置可以直接吃掉别人的棋子,吃几个。围棋可以在围住别人的情况下,吃掉别人的棋子。标准围棋的棋盘是19×19的,但小强只是想研究围棋的规则,故假定棋盘大小为n×n。
#include<bits/stdc++.h>
using namespace std;
int n;
vector<vector<char>> mat;
vector<vector<bool>> vit;
int main(){
cin>>n;
mat.resize(n,vector<char>(n));
vit.resize(n,vector<bool>(n));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>mat[i][j];
}
}
int mx[4] = {0,0,1,-1};
int my[4] = {1,-1,0,0};
function<int(int,int)> f = [&](int x,int y){
int ans=mat[x][y] == 'x';
bool isall = true;
bool iscan = false;
for(int i=0;i<4;i++){
int x_ = x + mx[i];
int y_ = y + my[i];
if(x_>=0 && y_>=0 && x_<n && y_<n && !vit[x_][y_]){
if(mat[x_][y_] == '.') return -1;
else if(mat[x_][y_] == 'o') continue;
else{
iscan = true;
vit[x_][y_]=true;
int res = f(x_,y_);
if(res!=-1){
ans += res;
isall = false;
}
}
}
}
if(isall && iscan){
return -1;
}
else{
return ans;
}
};
vector<vector<int>> ans;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(mat[i][j] == '.'){
vit[i][j]=true;
int res = f(i,j);
if(res>0)
ans.push_back({i+1,j+1,res});
}
}
}
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++){
cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<endl;
}
return 0;
} -
牛牛给出了一个关于未知量
x
的多项式。这个多项式以字符串的形式表示,它由若干个形如(x−d)
或(x+d)
的括号表达式相乘构成,其中d
是一个 1 到 9 之间的数字字符。牛牛想知道,当这个多项式完全展开后,x
的一次项(即x^1
项)的系数是多少?请计算这个系数,由于答案可能很大,请将答案对10007
取模后输出。#include<bits/stdc++.h>
using namespace std;
int main(){
string s;cin>>s;
vector<int> nums;
auto split = &{
int n = s.size();
int factor = 1;
int num=0;
for(int i=0;i<n;i++){
if(s[i] == 'x'||s[i] == '(') continue;
else if(s[i] == '-'){
factor = -1;
}
else if(s[i] == '+'){
factor = 1;
}
else if(isdigit(s[i])){
num = num * 10 + s[i] - '0';
}
else{
nums.push_back(num*factor);
num = 0;
}
}
};
int mod = 10007;
auto quickmi = [&](int value,int m){
int ans = 1;
int factor = value;
while(m){
if(m&1)
ans = (ans * factor)%mod;
factor = (factor * factor)%mod;
m>>=1;
}
return ans;
};
split();
int res = 1;
for(auto c:nums){
res = (res * c)%mod;
}
int total = 0;
for(auto c:nums){
total = (total + (res * quickmi(c,mod-2))%mod)%mod;
}
cout<<total<<endl;
return 0;
} -
给定一个整数,请你判断它是否可以写成4个质数之和。若可以,请输出任意一种方案;否则输出-1。
#include <iostream>
#include <cmath>
using namespace std;bool is_prime(long long x) {
if (x < 2) return false;
if (x == 2) return true;
if (x % 2 == 0) return false;
for (long long i = 3; i * i <= x; i += 2) {
if (x % i == 0) return false;
}
return true;
}int main() {
int t;
cin >> t;
while (t--) {
long long n;
cin >> n;
if (n % 2 == 0) {
long long m = n - 4;
for (long long p = 2; ; p++) {
if (is_prime(p) && is_prime(m - p)) {
cout << "2 2 " << p << " " << m - p << endl;
break;
}
}
} else {
long long m = n - 5;
for (long long p = 2; ; p++) {
if (is_prime(p) && is_prime(m - p)) {
cout << "2 3 " << p << " " << m - p << endl;
break;
}
}
}
}
return 0;
} -
小红有一个数组,她每次可以让两个相邻的数字一起加一,她想知道把数组变成左右对称的最小操作次数。
左右对称的意思是将数组整体翻转后与原数组一致,例如:{1,2,3,3,2,1},{4,0,4}都是左右对称的,而{8,1,0,9,7,5},{9,2,2,7,6,8}都不是左右对称的。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
vector<int> nums(n);for(int i=0;i<n;i++) cin>>nums[i];
int left = 0, right = n-1;
int count = 0;
while(left < right){
if(nums[left]!=nums[right]){
if(left == right - 1){
cout<<-1<<endl;
return 0;
}
else{
if(nums[left] > nums[right]){
count += nums[left] - nums[right];
nums[right-1] += nums[left] - nums[right];
nums[right] = nums[left];
}
else{
count += nums[right] - nums[left];
nums[left+1] += nums[right] - nums[left];
nums[left] = nums[right];
}
}
}
left++;
right--;
}
cout<<count<<endl;
return 0;
}
- 给出一个长度为n的序列a1,a2,...,n,求取出k个不同的区间,要求满足取出区间的区间和是t的倍数,求它们的区间和相加最大是多少?
一个区间的区间和即里面所有数相加,例如a=[4,3,5],区间[1,2]的和为7,区间{1,3]的和为12。
保证至少存在k个合法的区间。
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int main(){
int n,k,t;
cin>>n>>k>>t;
vector<int> nums(n);for(int i=0;i<n;i++) cin>>nums[i];
vector<ll> pre(n+1);
for(int i=1;i<=n;i++){
pre[i] = pre[i-1] + nums[i-1];
}
priority_queue<ll, vector<ll>, greater<ll>> pq;
vector<vector<int>> mem(t);
mem[0].push_back(0);
for(int i=1;i<=n;i++){
int m = pre[i]%t;
for(int j=0;j<mem[m].size();j++){
if(pq.size()>=k && pre[i]-pre[mem[m][j]]>pq.top()){
pq.pop();
}
pq.push(pre[i]-pre[mem[m][j]]);
}
mem[m].push_back(i);
}
ll ans = 0;
while(!pq.empty()){
ans += pq.top();
pq.pop();
}
cout<<ans<<endl;
return 0;
}