2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)-正式赛 部分题解

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)-正式赛 部分题解相关的知识,希望对你有一定的参考价值。

比赛链接

http://oj.saikr.com/contest/19

B.Error

思路

这道题其实我们贪心加上二分就能做了,首先我们贪心得把 b [ 1 ] b[1] b[1] 变得很小,然后构造 b [ i ] b[i] b[i] 的时候也是贪心的去构造,尽可能比 b [ i − 1 ] b[i-1] b[i1]大1,如果不行的话就让 b [ i ] = b [ i ] − e p s b[i] = b[i] - eps b[i]=b[i]eps ,然后我们对这个 e p s eps eps 的值进行二分查找就好了,详情请看代码

代码

#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define int long long
int dx[4] = -1, 0, 1, 0, dy[4] = 0, 1, 0, -1;

ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;
//----------------自定义部分----------------
int t,n,m,q,a[N],b[N];

bool check(int eps)
	for(int i = 1;i <= n; ++i) b[i] = a[i];
	b[1] -= eps;
	b[1] = max(1LL,b[1]);
	for(int i = 2;i <= n; ++i) 
		if(b[i] + eps <= b[i - 1]) return false;
		if(b[i] - eps > b[i - 1])
				b[i] -= eps;
		else 
			if(b[i] + eps > b[i-1])
				b[i] = b[i-1] + 1;
			else return false;
		
		b[i] = max(0LL,b[i]);
	
//	for(int i = 1;i <= n; ++i) cout<<b[i]<<" \\n"[i == n];
	return true;


void slove()
	cin>>n;
	for(int i = 1;i <= n; ++i) cin>>a[i];
	int l = 0,r = 1e9+10;
	while(l < r) 
		int mid = l + r >> 1LL;
		if(check(mid)) r = mid;
		else l = mid + 1;
	
	cout<<r<<endl;


signed main()

	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	t = 1;
	while(t--)
		slove();
	
	
	return 0;

E.吃利息

思路

按照他说的一步一步模拟就好了,注意的是:

  • 先计算利息,再加上多的5金币
  • 利息最多5块

代码

#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f

int dx[4] = -1, 0, 1, 0, dy[4] = 0, 1, 0, -1;

ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;
//----------------自定义部分----------------
int t,k,n,m,q,a[N];
void slove()
	cin>>k>>n;
	ll ans = k,cnt = 0;
	for(int i = 1;i <= n; ++i) 
		ans += min(ans/10,5LL);
		ans += 5;
	
	cout<<ans<<endl;


int main()

	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	t = 1;
	while(t--)
		slove();
	
	
	return 0;

F.Star

思路

计算凸包连边的概率就好,然后正常求凸包面积
ps:代码是借用的别人的模板

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;

//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define int long long

int dx[4] = -1, 0, 1, 0, dy[4] = 0, 1, 0, -1;
ll t;
ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

//----------------自定义部分----------------
int n;
const int maxn=55;

struct point
	double x,y;
	point (double a=0,double b=0):x(a),y(b);
	point operator + (const point &a)const
		return point (x+a.x,y+a.y);
	
	point operator - (const point &a)const
		return point (x-a.x,y-a.y);
	
	double operator * (const point &a)const
		return x*a.y-y*a.x;
	
	friend double dist(const point &a)
		return a.x*a.x+a.y*a.y;
	
	bool operator < (const point &a)const
		if (x!=a.x) return x<a.x;
		else return y<a.y;
	
;

class Constellation
private:
	double pr[maxn];
	point nod[maxn];
	int n;
public:
	double expectation(vector <double> x, vector <double> y, vector <double> prob)
		double ans=0;
		n=x.size();
		for (int i=0;i<n;++i)
			nod[i]=point(x[i],y[i]);
			pr[i]=prob[i];
		
		
		//枚举所有有向边。 
		for (int i=0;i<n;++i)
			for (int j=0;j<n;++j) if (i!=j)
			double tmp=1;
			point use=nod[j]-nod[i];
			
			//计算这条边在凸包上的概率 
			for (int k=0;k<n;++k) if (i!=k&&j!=k)
				if (use*(nod[k]-nod[i])>0) tmp*=(1-pr[k]);
				else if (use*(nod[k]-nod[i])>-1e-12&&dist(nod[i]-nod[k])<dist(nod[j]-nod[i]))
					tmp*=(1-pr[k]);
			
			
			//累计答案 
			ans+=tmp*(nod[i]*nod[j])*pr[i]*pr[j];
		
		
		//注意要除以2 ... 
		ans/=2;
		return fabs(ans);
	
CC;

void slove()
	vector <double> x,y,prob;
	double a,b,c;
	cin>>n;
	for(int i = 0;i < n; ++i)
		cin>>a>>b>>c;
		x.push_back(a);
		y.push_back(b);
		prob.push_back(c);
	
	cout << fixed << setprecision(6);
	cout<<CC.expectation(x,y,prob)<<endl;
		


signed main()

	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	t = 1LL;
	while(t--) 
		slove();
	
	
	return 0;

G.MP4

思路

实际上就是求解字典序第 k k k 小的数字,可以在leetcode找到原题:440. 字典序的第K小数字 ,实际上这题做法很多样,可以直接搜索,也可以看规律模拟(不知道为啥我的模拟写炸了,对拍到1e7的数据都没问题)

代码

模拟代码:

#include<bits/stdc++.h>
using namespace std;
//----------------×Ô¶¨Ò岿·Ö----------------
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define int long long

int dx[4] = -1, 0, 1, 0, dy[4] = 0, 1, 0, -1;

ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;
//----------------×Ô¶¨Ò岿·Ö----------------
int t,n,m,q,a[N];

map<int,bool> vis;

void slove()
	cin>>n;
	int cnt = 0;
	int p;
	for(int i = 1LL;i <= 9LL; ++i) 
		p = n;
		int j = i,c = 1LL;
		for(;j <= p; j *= 10LL,c *= 10LL)
			if(vis[j]) continue;
			vis[j] = true;
			cnt++;
			cout<<j<<".mp4"<<endl;
			if(cnt == 50) return;
		
		if(j > p)
			j/=10LL,c/=10LL;
		for(int l = j;l > 1LL; l/=10LL,c/=10LL)
			int k = 1L

以上是关于2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)-正式赛 部分题解的主要内容,如果未能解决你的问题,请参考以下文章

2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)-正式赛 部分题解

2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛正式赛) 部分题题解

2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛正式赛) 部分题题解

2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)- 占座位(最小割)

2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)- 占座位(最小割)

2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)- 占座位(最小割)