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>y0且yb<y0 说明球在篮筐前沿时在篮筐之上,在篮筐后沿时在篮筐之下,篮球在此中间掉入篮筐,得分;若
y
a
>
y
0
且
y
b
>
y
0
y_a>y_0且y_b>y_0
ya>y0且yb>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+x1−x0 代替,因为翻转后算出的
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=2n−1
#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网络赛重赛-题解的主要内容,如果未能解决你的问题,请参考以下文章
CCPC网络赛2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) 签到题5题
2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)