★
J-plan
有n个学生要去旅行。酒店有两种类型的房间:双人房和三人间。双人房的价格是p2,三人房的价格是p3
现在你需要计算这些学生的最低总成本。
求得最小公倍数为6
当 p32 >= p23 时(双人间更实惠)
两种情况:
一:当n%2 == 0 即刚好双人间可住满 , 输出 n/2 p2
二:当n%2 == 1 可分为两种方案,剩一个人住双人间和剩三个人住三人间 去最小值:
min( n/2p2+p2 , (n/2-1)p2+p3 )
当 p32 < p23 时
三种情况:
if( n%3 == 0 ) cout << n/3p3 << endl ;三人间住满
else if( n%3 == 1 ) cout << min( n/3p3+p2 , (n/3-1)p3+2p2 ) << endl ;余下一个人,选择双人间或者余下四人选两个双人间
else cout << min( n/3p3+p2 , n/3*p3+p3 ) << endl ;余下两个人,选择双人间或者选三人间
AC代码:
void solve()
{
int n , p2 , p3 ;
cin >> n >> p2 >> p3 ;
if( p3*2 >= p2*3 ){
if( n%2 == 0 ) cout << n/2 *p2 << endl ;
else cout << min( n/2*p2+p2 , (n/2-1)*p2+p3 ) << endl ;
}
else {
if( n%3 == 0 ) cout << n/3*p3 << endl ;
else if( n%3 == 1 ) cout << min( n/3*p3+p2 , (n/3-1)*p3+2*p2 ) << endl ;
else cout << min( n/3*p3+p2 , n/3*p3+p3 ) << endl ;
}
return ;
}
★
G-Max
给出两个正整数c,n。你需要找到一对满足1<=a,b<=n的整数(a,b),a和b的最大公除法是c。你需要最大化a和b的乘积
当c > n 时 无解
当 n==c 时 输出 cc
当c < n 时 输出 cc*(n/c)*(n/c-1)
★★
A-gpa
经典二分 对于答案 res,
∑
i
=
1
n
s
[
i
]
∗
c
[
i
]
∑
i
=
1
n
s
[
i
]
\frac{\sum_{i=1}^ns[i]*c[i]}{\sum_{i=1}^ns[i]}
∑i=1ns[i]∑i=1ns[i]∗c[i] > res
<=>
∑
i
=
1
n
s
[
i
]
∗
c
[
i
]
\sum_{i=1}^ns[i]*c[i]
∑i=1ns[i]∗c[i] >
∑
i
=
1
n
(
s
[
i
]
∗
r
e
s
)
\sum_{i=1}^n(s[i]*res)
∑i=1n(s[i]∗res)
<=>
∑
i
=
1
n
s
[
i
]
∗
(
c
[
i
]
−
r
e
s
)
\sum_{i=1}^ns[i]*(c[i]-res)
∑i=1ns[i]∗(c[i]−res) > 0
sort一遍减去最小的k个即可
AC代码:
int n , k ;
double s[N] ;
double c[N] ;
double w[N] ;
bool cmp( double x , double y )
{
return x > y ;
}
int check( double x )
{
double ans = 0 ;
for( int i = 1 ; i <= n ; i ++ ){
w[i] = s[i]*( c[i] - x ) ;
}
sort( w+1 , w+n+1 , cmp ) ;
for( int i = 1 ; i <= n-k ; i ++ ){
ans += w[i] ;
}
if( ans >= 0 ) return 1 ;
return 0 ;
}
void solve()
{
cin >> n >> k ;
for( int i = 1 ; i <= n ; i ++ ){
cin >> s[i] ;
}
for( int i = 1 ; i <= n ; i ++ ){
cin >> c[i] ;
}
double l = 0 ;
double r = 1e3 ;
while( r-l > 0.000001 ){
double mid = ( l+r ) / 2.0 ;
if( check( mid ) ) l = mid ;
else r = mid ;
}
cout << fixed << setprecision(10) << l << endl ;
return ;
}
★★★★
B-div
题意:求 x
∈
\in
∈ {
n
2
+
1
n^2+1
n2+1 ,
n
2
+
2
n
n^2+2n
n2+2n } 满足 x 是
n
4
n^4
n4 的因子
规律推算
∵
\because
∵ x
∈
\in
∈ {
n
2
+
1
n^2+1
n2+1 ,
n
2
+
2
n
n^2+2n
n2+2n } 即
n
2
+
a
n^2+a
n2+a( 1 <= a <= 2n )是
n
4
n^4
n4 的因子
又
n
4
n^4
n4 - (
n
2
+
a
n^2+a
n2+a)(
n
2
−
a
n^2-a
n2−a) =
a
2
a^2
a2
∴
\therefore
∴
n
2
+
a
n^2+a
n2+a 是
a
2
a^2
a2 的 因子
即 (
n
2
+
a
n^2+a
n2+a)*m =
a
2
a^2
a2
又 a <= 2n 故可得 m < 4 ,即 m = 1 ,2 ,3 ;
暴力枚举推算得到方程有两个
1:
n
2
n_2
n2 =
6
n
1
6n_1
6n1-
n
0
n_0
n0(
n
0
n_0
n0=0 ,
n
1
n_1
n1=2)
2:
n
2
n_2
n2 =
14
n
1
14n_1
14n1-
n
0
n_0
n0(
n
0
n_0
n0=0 ,
n
1
n_1
n1=6)
AC代码(python):
m = int(input())
x = 0
y = 2
while x<m:
t = 6*y-x
x = y
y = t
ans = x
x = 0
y = 6
while x<m:
t = 14*y-x
x = y
y = t
ans = min(ans, x)
print(ans)
★★★★
F-take
Kanade有n个盒子,第i个盒子有**p[i]概率有d[i]**大小的钻石。
起初,卡纳德有一颗0号的钻石。她将从1号到n号打开盒子。当她打开一个盒子时,如果盒子里有一颗钻石,而且它比她的钻石大,她会用她的钻石替换它。
现在需要计算预期的替换数量。
您只需要输出%998244353。
数学期望+树状数组
E(a+b+c+d…) = E(a)+E(b)+E©+…
枚举每个盒子的期望即可,因为盒子只有打开与不打开两种情况即0和1
sort钻石大小,从大到小排列,保证每次开第i个宝箱时,前面宝箱一定不打开
故推算公式为
∏
j
=
1
i
−
1
(
100
−
p
[
j
]
)
∗
p
[
i
]
\prod_{j=1}^{i-1}( 100-p[j] )*p[i]
∏j=1i−1(100−p[j])∗p[i] ,
i
∈
(
1
,
n
)
i\in(1,n)
i∈(1,n)
AC代码:
int QuickPow( int x , int pow )
{
int res = 1 ;
x %= Max ;
// x %= mod ;
while( pow ){
if( pow & 1 ) res = ( res * x ) % Max ;
// if( pow & 1 ) res = ( res * x ) % mod ;
// if( pow & 1 ) res = res * x ;
x = ( x * x ) % Max ;
// x = ( x * x ) % mod ;
// x = x*x ;
pow >>= 1 ;
}
return res % Max ;
// return res ;
// return res % mod ;
}
int gcd( int a , int b )
{
if(!b) return a ;
return gcd( b , a%b ) ;
}
// 解决方案代码区--------------------------------------------------
const int N = 1e5+7 ;
const int M = 2e6+7 ;
struct node
{
int w ;
int p ;
int id ;
/* data */
};
node a[N] ;
int b[N] ;
int n ;
int lowbit( int x )
{
return x & (-x) ;
}
bool cmp( node x , node y )
{
if( x.w == y.w ) return x.id < y.id ;
return x.w > y.w ;
}
int mul( int x )
{
int ans = 1 ;
while( x ){
ans = ( ans*b[x] )%Max ;
x -= lowbit(x) ;
}
return ans ;
}
void add( int x , int p )
{
while( x <= n ){
b[x] = ( b[x]*p )%Max ;
x += lowbit( x ) ;
}
}
void solve()
{
cin >> n ;
for( int i = 1 ; i < N ; i ++ ) b[i] = 1 ;
for( int i = 1 ; i <= n ; i ++ ){
cin >> a[i].p >> a[i].w ;
a[i].id = i ;
// cout << b[i] << endl ;
}
sort( a+1 , a+n+1 , cmp ) ;
int res = 0 ;
for( int i = 1 ; i <= n ; i ++ ){
res = ( res + 1ll*mul( a[i].id )%Max*( a[i].p%Max*( QuickPow( 100 , Max-2 )%Max )%Max)%Max )%Max ;
// cout <<res << endl ;
add( a[i].id , QuickPow( 100 , Max-2 )%Max*(100-a[i].p)%Max ) ;
}
cout << res << endl ;
return ;
}