2021CCPC网络赛重赛-题解

Posted iuk11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021CCPC网络赛重赛-题解相关的知识,希望对你有一定的参考价值。

(自己可能真的是个废物,理不出逻辑,错在小细节,不敢开新题,新题更没把握)
难过周末。


1002

题意:
拿球投篮, ( x 0 , y 0 ) 到 ( x 1 , y 0 ) (x_0,y_0)到(x_1,y_0) (x0,y0)(x1,y0)为篮筐长, ( x 1 , y 1 ) 到 ( x 2 , y 2 ) 为 篮 板 长 (x_1,y_1)到(x_2,y_2)为篮板长 (x1,y1)(x2,y2),不能磕到篮筐,及不能等于边界,篮球被看作一个质点,给定一条抛物线 y = a x 2 + b x + c y=ax^2+bx+c y=ax2+bx+c,给定参数 a , b , c a,b,c a,b,c,问篮球能不能投进篮筐。两种方式投进:直接投进;打板,碰到篮板后抛物线会沿着 x = x 1 x=x_1 x=x1水平翻转,然后射入篮筐。
分析:
该题与射出起点无关,因为抛物线为定值:
(1)考虑篮球能否直接投进;
(2)考虑篮球反弹篮板后能否投进。
首先带入 x 0 , x 1 x_0,x_1 x0,x1,分别计算出篮球到该位置的时候的高度 y a , y b y_a,y_b ya,yb,若 y a > y 0 且 y b < y 0 y_a>y_0且y_b<y_0 ya>y0yb<y0 说明球在篮筐前沿时在篮筐之上,在篮筐后沿时在篮筐之下,篮球在此中间掉入篮筐,得分;若 y a > y 0 且 y b > y 0 y_a>y_0且y_b>y_0 ya>y0yb>y0 说明篮筐此时不会掉入篮筐,仍在篮筐之上,判断是否会打板 y b < = y 2 y_b<=y_2 yb<=y2 说明会打板,再次求出打板后落到篮筐时的位置,可以用 x = x 1 + x 1 − x 0 x=x_1+x_1-x_0 x=x1+x1x0 代替,因为翻转后算出的 y y y值在同一水平线。若该值比 y 0 y_0 y0小,则说明可以落入篮筐,得分;除这两种情况,其它情况均不得分。

#include<iostream>
using namespace std;
double a,b,c;
double x0,x1,y00,y11,y22;
int main()
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
		cin>>a>>b>>c;
		cin>>x0>>x1>>y00>>y11>>y22;
		double ya=a*x0*x0+b*x0+c;
		double yb=a*x1*x1+b*x1+c;
		//cout<<y0<<" "<<ya<<" "<<yb<<endl;
		if(ya>y00&&yb<y00)
			cout<<"Yes"<<endl;
		else if(ya>y00&&yb>y00)
			//cout<<yb<<" "<<y2<<endl;
			if(yb<=y22)
				double xx=2*x1-x0;
				double yc=a*xx*xx+b*xx+c;
				if(yc<y00) cout<<"Yes"<<endl;
				else cout<<"No"<<endl;
			else
				cout<<"No"<<endl;
			
		else
			cout<<"No"<<endl;
		
	
	return 0;

1004

题意:
定义一个函数 f ( x ) = k f(x)=k f(x)=k,k是第一个大于x的质数。
然后给定x的值,问 ( f ( x ) + f ( f ( x ) ) ) / 2 (f(x)+f(f(x)))/2 (f(x)+f(f(x)))/2下取整的结果是不是质数,如果是质数就输出YES,否则输出NO
分析:
因为f(x)f(f(x))均为质数,且为相邻的两个质数,除2外所有的质数均为奇数,且除了x=1时得到的值为2 3,其它情况下均可以得到两个不连续的质数,那么加和除以二的结果一定在这两个质数中间,两质数中间的数均为合数,且结果向下取整一定为整数,所有只要不是2 3一组的质数,其它相邻两个质数和除以二的结果一定为合数。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int main()
	ios::sync_with_stdio(false);
	int t;
	long long x;
	cin>>t;
	while(t--)
		cin>>x;
		if(x==1) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	
	return 0;

1006

题意就是
前缀为nunhehheh,后缀为若干个a(不包括0个),给定一个字符串,问有多少个满足条件的子序列。
分析:
先倒序维护一个在当前位置a有多少个的数组。
再动态维护出一个 d p [ i ] [ j ] dp[i][j] dp[i][j],表示在第i位以第j个操作数 结尾的子序列个数。
o p p = " @ n u n h e h h e h " opp="@nunhehheh" opp="@nunhehheh",第一位空出,防止 i = 0 i=0 i=0时数组越界。
每次在第i位上记录(该位满足的a的组合数,乘以,该位有多少个满足前缀要求的子序列)
设n为当前位后面的a的数量: C n 1 + C n 2 + . . . + C n n = 2 n − 1 C_n^1+C_n^2+...+C_n^n=2^n-1 Cn1+Cn2+...+Cnn=2n1

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
const int mod=998244353;
const int N=1e5+100;
typedef long long ll;
ll nua[N];
ll dp[12];
string opp="@nunhehheh";
ll qpow(int a,int b)
	ll res=1;
	while(b)
		if(b&1) res=res*a%mod;
		a=1LL*a*a%mod;
		b>>=1;
	
	return res;

int main()
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
		memset(nua,0,sizeof(nua));
		memset(dp,0,sizeof(dp));
		string str;
		cin>>str;
		int n=str.size();
		str="@"+str;
		for(int i=n;i>=1;i--)
			nua[i]=nua[i+1]+(str[i]=='a');
		
		ll ans=0,temp=0;
		for(int i=1;i<=n;i++)
			for(int j=9;j>=2;j--)
				dp[j]=(dp[j]+(str[i]==opp[j])*dp[j-1])%mod;
			
			dp[1]=(dp[1]+(str[i]==opp[1]))%mod;;
			ans=(ans+(dp[9]-temp+mod)%mod*(qpow(2,nua[i])-1+mod)%mod)%mod;
			temp=dp[9]%mod;
		
		cout<<ans<<endl;
	
	return 0;	
 

以上是关于2021CCPC网络赛重赛-题解的主要内容,如果未能解决你的问题,请参考以下文章

Jumping Monkey(CCPC网络赛重赛)

CCPC网络赛2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) 签到题5题

2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)

2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)

2021CCPC网络赛部分题解

2021CCPC网络选拔赛题解