曲阜师范大学2023年暑期大一新生排位赛 题解

目录

A (1). Sum 详细点击:sum      //整除分块

B (2). Sort

C (3). String                              //字符串dp

D (4). Factor                ​​​​​​​        ​​​​​​​     //素数筛变式

E (5). Tree                ​​​​​​​        ​​​​​​​        //树形dp

F (6). Geometry                        //几何

G (7). Graph                         ​​​​​​​    //二分答案

H (8). Line                                //贪心

I (9). And / Or                       ​​​​​​​    //位运算

J (10). Mov                ​​​​​​​               //模拟


A (1). Sum 详细点击:sum

#include
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

ll T,x,y;

void solve() {
	ll res=0;
	cin>>x>>y;
	ll i=min((ll)sqrt(x),y);
	while(i*i+i+1>x)
		i--;
	res=(1+i)*i/2;
	for(ll l=i+1,r; l<=y,l+1<=x; l=r+1) {
		r=x/(x/(l+1))-1;
		r=min(r,y);
		if(l>r)
			break;
		res+=x/(l+1)*(r-l+1);
	}
	cout<>T;
	while(T--)
		solve();
	return 0;
}

B (2). Sort

使用stable_sort强行卡过,优化可了解:sort 学长Ashy深情讲解

#include
using namespace std;

struct node {
	long long x,y;
} d[100001];
long long e[100001];
long long n,q,t,u,v;

bool cmp(node a,node b) {
	return a.x==b.x?a.y>n>>q;
	for(long long i=1; i<=n; i++)
		cin>>d[i].x,d[i].y=i;
	/*
	for(int i=1; i<=n; i++)
		cout<>t;
		if(t==1) {
			cin>>u>>v;
			d[e[u]].x=v;
			stable_sort(d+1,d+1+n,cmp);
			for(int i=1; i<=n; ++i)
				e[d[i].y]=i;
		} else {
			cin>>u;
			cout<

在这提一下stable_sort和sort的区别,单纯从性能来讲sort性能更好,因为stable_sort要维护数据的稳定性,丧失了一部分性能,但在大部分数据顺序不变的情况下,stable_sort要比sort快很多

C (3). String

字符串dp,即区间dp

#include
using namespace std;
//最长回文串子序列

int n;
string s;
int dp[2100][2100];
//字符串s在区间[i, j]范围内的最长回文子序列的长度
//dp[i][j] = dp[i+1][j-1] + 2;
//dp[i][j] = (dp[i+1][j] > dp[i][j-1]) ? dp[i+1][j] : dp[i][j-1];

int main() {
	cin>>n>>s;
	for (int i=0;idp[i][j-1])?dp[i+1][j]:dp[i][j-1];
			}
		}
	}
	cout<

D (4). Factor

用埃式筛暴力筛出来的,时间复杂度为O(nlogn)

#include
using namespace std;
const int maxn=1e6+1;

int n,a,ans;
bool vis[maxn];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>a,vis[a]=true;
	for(int i=1; i<=maxn; i++)
		for(int j=i; j<=maxn; j+=i)
			if(vis[j]) {
				ans++;
				break;
			}
	cout<

E (5). Tree

树形DP模板题

#include
using namespace std;
typedef long long ll;
const ll N=1e6+10;

ll a[N],u,v;
ll f[N],tot;
struct Edge {
	int to,next;
} edges[N];
int head[N],edge_len,n;

void Add(int from,int to) {
	edges[++edge_len].next=head[from];
	edges[edge_len].to=to;
	head[from]=edge_len;
}
void Dfs(ll e,ll fa) {
	bool flag=0;
	f[e]+=a[e];
	for(int i=head[e]; ~i; i=edges[i].next) {
		if(edges[i].to!=fa) {
			flag=1;
			Dfs(edges[i].to,e);
			f[e]+=f[edges[i].to];
		}
	}
}

int main() {
	memset(head,-1,sizeof head);
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>a[i],tot+=a[i];
	for(int i=1; i>u>>v;
		Add(u,v);
		Add(v,u);
	}
	Dfs(1,0);
	ll mx=0;
	for(int i=2; i<=n; i++)
		mx=max(mx,abs(f[i]-(tot-f[i])));
	cout<

F (6). Geometry

曲阜师范大学2023年暑期大一新生排位赛 题解_第1张图片

把梯形补成三角形 

曲阜师范大学2023年暑期大一新生排位赛 题解_第2张图片

 补出来的三角形与等腰三角形是相似三角形,通过三角形相似我们可以得出来

\frac{h+H}{\frac{a}{2}}=\frac{c}{r}

H+d=\sqrt{r^2+c^2}

\frac{h+H}{a}=\frac{H}{b}

通过以上三式解方程就可以了。

#include
using namespace std;
//梯形补成三角形
//按照比求三角形高与H圆心到三角形顶点的距离d+H
//H=b/(a-b)*h
//c=r*h*2/(a-b)
//d+H=sqrt(c*c+r*r)

double r,a,b,c,h,H,d;

int main() {
	cin>>r>>a>>b>>h;
	if(2*r

G (7). Graph

二分答案,judge函数用于判断给定的时间t是否满足从起点x到终点y的路径存在。

#include
using namespace std;
const int N=2e6+10;
typedef long long ll;

int n,m,x,y;
int head[N],edge_len;
struct edge {
	int next,to;
	ll w;
} edges[N];
int u[N],v[N],w[N];
bool vis[N];

void Add(int from,int to,ll w) {
	edges[++edge_len].next=head[from];
	edges[edge_len].to=to;
	edges[edge_len].w=w;
	head[from]=edge_len;
}
void Dfs(int e) {
	if(vis[e])
		return;
	vis[e]=true;
	for(int i=head[e]; ~i; i=edges[i].next) {
		if(!vis[edges[i].to])
			Dfs(edges[i].to);
	}
}
bool judge(int t) {
    for(int i=0;i<=n;++i)
        head[i]=-1,vis[i]=false;
	edge_len=0;
	for(int i=0; it)
			continue;
		Add(v[i],u[i],w[i]);
	}
	Dfs(x);
	return vis[y];
}

int main() {
    ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);

	cin>>n>>m>>x>>y;
	for(int i=0; i>u[i]>>v[i]>>w[i];
	int l=0,r=1e9,mid;
	while(l>1;
		if(judge(mid))
			r=mid;
		else
			l=mid+1;
	}
	cout<

H (8). Line

贪心的思想,按边的右端点排序,以第一个右端点向右扩大k,找到第一个超出此范围的左端点,并将其右端点作为新的lc

#include
using namespace std;
typedef long long ll;

ll n,k,cnt;
struct node {
	ll l,r;
} d[1000001];

bool cmp(node a,node b) {
	return (a.r==b.r)?a.l>n>>k;
	for (int i=0; i>d[i].l>>d[i].r;
	sort(d,d+n,cmp);
	ll lr=d[0].r+k;
	for (int i=1; i

I (9). And / Or

我们知道按位或是不进位加法,a|b\geq a,b 恒成立。

因此只要把每个数进行按位与操作就可以得到最大值

#include
using namespace std;

int n,a[100001],ans;

int main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		ans|=a[i];
	}
	cout<

J (10). Mov

模拟题,没啥好说的

#include
using namespace std;

int n;
string s,t;
int a[1000001];

int main() {
	cin>>n;
	while(n--) {
		cin>>s>>t;
		//cout<'9') {
				int y=0;
				for(int j=i+2; j

你可能感兴趣的:(cocoa,macos,objective-c)