蓝桥杯之贪心 Posted 2023-04-04 Selvaggia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯之贪心相关的知识,希望对你有一定的参考价值。
蓝桥杯之贪心
将股票价格的变动抽象成折线图,将每个上升阶段累加起来(每次的累加并不一定代表真实的一次买卖交易,比如两段连续上升的折线,只进行了一次买卖,但对两段上升折线分别累加的收益结果是一致的)
# include <ios tream>
using namespace std;
# define int long long int
const int N= 105 ;
int n, x;
signed main ( )
cin>> n;
int res= 0 ;
int buy;
for ( int i= 1 ; i<= n; i++ )
cin>> x;
if ( i== 1 ) buy= x;
if ( x> buy)
res+= ( x- buy) ;
buy= x;
else buy= x;
cout<< res;
return 0 ;
我们设在仓库左边的所有点,到仓库的距离之和为p,右边的距离之和则为q,那么我们就必须让p+q的值尽量小 假设货舱建的位置,左边有 k 家商店,右边有 n-k 家商店,假设 货舱向左移动 x 的距离,那么此时总共的路程为
p
−
k
∗
x
+
q
+
(
n
−
k
)
∗
x
=
p
+
q
+
n
∗
x
−
2
∗
k
∗
x
=
p
+
q
+
(
n
−
2
∗
k
)
∗
x
p-k*x+q+(n-k)*x=p+q+n*x-2*k*x=p+q+(n-2*k)*x
p − k ∗ x + q + ( n − k ) ∗ x = p + q + n ∗ x − 2 ∗ k ∗ x = p + q + ( n − 2 ∗ k ) ∗ x ,k==n/2
# include <bits/stdc++.h>
using namespace std;
# define int long long int
const int N= 1e5 + 5 ;
int n, x;
int a[ N] ;
signed main ( )
cin>> n;
int res= 0 ;
int mid= ( n+ 1 ) / 2 ;
for ( int i= 1 ; i<= n; i++ )
cin>> a[ i] ;
sort ( a+ 1 , a+ n+ 1 ) ;
for ( int i= 1 ; i<= n; i++ )
res+= abs ( a[ mid] - a[ i] ) ;
cout<< res;
return 0 ;
根据右端点排序 注意点,node类型,每个区间段的左右端点必须精确到double,还有上一个取点的位置,也必须精确到double
# include <bits/stdc++.h>
using namespace std;
# define int long long int
const int N= 1e5 + 5 ;
int n, d;
struct node
double l, r;
bool operator < ( const node & a) const
return r< a. r;
range[ N] ;
signed main ( )
cin>> n>> d;
int x, y;
int flag= false ;
for ( int i= 1 ; i<= n; i++ )
cin>> x>> y;
if ( y> d)
flag= true ;
cout<< "-1" ;
return 0 ;
range[ i] . l= x- sqrt ( d* d- y* y) ;
range[ i] . r= x+ sqrt ( d* d- y* y) ;
if ( flag)
cout<< "-1" ;
return 0 ;
sort ( range+ 1 , range+ n+ 1 ) ;
int res= 0 ;
double pre= - 2000 ;
for ( int i= 1 ; i<= n; i++ )
if ( pre< range[ i] . l)
res++ ;
pre= range[ i] . r;
cout<< res;
return 0 ;
pair自动排序
# include <bits/stdc++.h>
using namespace std;
# define int long long int
# define pdd pair< double , double >
const int N= 1e5 + 5 ;
int n, d;
pdd range[ N] ;
signed main ( )
cin>> n>> d;
int x, y;
int flag= false ;
for ( int i= 1 ; i<= n; i++ )
cin>> x>> y;
if ( y> d)
flag= true ;
cout<< "-1" ;
return 0 ;
range[ i] = x+ sqrt ( ( double ) d* d- y* y) , x- sqrt ( ( double ) d* d- y* y) ;
if ( flag)
cout<< "-1" ;
return 0 ;
sort ( range+ 1 , range+ n+ 1 ) ;
int res= 0 ;
double pre= - 20000000 ;
for ( int i= 1 ; i<= n; i++ )
if ( pre+ 1e-5 < range[ i] . second)
res++ ;
pre= range[ i] . first;
cout<< res;
return 0 ;
# include <bits/stdc++.h>
using namespace std;
# define int long long int
const int N= 5e5 + 5 ;
int n, s;
int a[ N] ;
signed main ( )
cin>> n>> s;
int x, y;
double res;
double AVG= 1.0 * s/ n;
for ( int i= 1 ; i<= n; i++ )
cin>> a[ i] ;
sort ( a+ 1 , a+ n+ 1 ) ;
double avg= AVG;
for ( int i= 1 ; i<= n; i++ )
if ( a[ i] < avg)
res+= ( a[ i] - AVG) * ( a[ i] - AVG) ;
s-= a[ i] ;
avg= 1.0 * s/ ( n- i) ;
else
s= 0 ;
res+= ( avg- AVG) * ( avg- AVG) * ( n- i+ 1 ) ;
break ;
res/= n;
res= sqrt ( res) ;
cout<< fixed<< setprecision ( 4 ) << res;
return 0 ;
输入样例1:
5 3
- 100000
- 10000
2
100000
10000
输出样例1:
999100009
输入样例2:
5 3
- 100000
- 100000
- 2
- 100000
- 100000
输出样例2:
- 999999829
大佬思路
K是奇数,需要转化为K是偶数的情况,于是先取一个数,为了使得结果最大,取最大的数(正数的话绝对值最大,负数的话(K是奇数且最大值是负数,res一定是负数),最大的负数绝对值最小也能使得res尽可能大
转化为选取偶数的情况,将n个数两两合并后,取 K/2个数。怎么进行合并,首先如果n是偶数,两两合并正好,n若是奇数,剩下的一个数可能是正数(n中有奇数个正数),不进行合并,剩下的一个数可能是负数(n中有奇数个负数),取K/2个数时直接略过这个负数
为什么要从左右两端开始两两合并?因为最大值只可能出现在两段。最右端如果俩正数,最左端如果俩负数,相乘得到的绝对值是尽可能大的(sign是考虑到是否一开始就乘了一个负数),因为数组是经过排序的,绝对值最小的数一定在两段被排除的一端或者是中间(绝对值的乘积是最小的),因此只要考虑两边得到绝对值尽可能大的乘积,中间可以直接不考虑
注意取余顺序—— res%mod,res先取余是没有意义的,res%mod*lt
计算到这里时就已经爆longlong了
res= lt% mod* res% mod; ✔
# include <bits/stdc++.h>
using namespace std;
# define int long long int
const int N = 100010 , mod = 1000000009 ;
int n, k;
int a[ N] ;
signed main ( )
cin>> n>> k;
for ( int i= 1 ; i<= n; i++ )
cin>> a[ i] ;
sort ( a+ 1 , a+ 1 + n) ;
int res= 1 ;
int sign= 1 ;
int l= 1 , r= n;
if ( k& 1 )
res= a[ r] ;
if ( res< 0 ) sign= - 1 ;
r-- ;
k-- ;
while ( k)
int lt= a[ l] * a[ l+ 1 ] ;
int rt= a[ r] * a[ r- 1 ] ;
if ( lt* sign> rt* sign)
l+= 2 ;
res= lt% mod* res% mod;
else
r-= 2 ;
res= rt% mod* res% mod;
k-= 2 ;
cout<< res;
return 0 ;
蓝桥杯之FJ的字符串
基础练习 FJ的字符串
时间限制:1.0s 内存限制:512.0MB
问题描述
FJ在沙盘上写了这样一些字符串:
A1 = “A”
A2 = “ABA”
A3 = “ABACABA”
A4 = “ABACABADABACABA”
… …
你能找出其中的规律并写所有的数列AN吗?
输入格式
仅有一个数:N ≤ 26。
输出格式
请输出相应的字符串AN,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。
样例输入
3
样例输出
ABACABA
C++中含有string这一个类,所以使用C++进行递归应该会比C更方便,下面是C++
1 #include<iostream>
2 using namespace std;
3 string dts(int n);
4 int main(){
5 int n;
6 scanf(" %d " ,&n);
7 cout<<dts(n);
8 return 0 ;
9 }
10 string dts(int n){
11 if (n==1 )
12 return " A " ;
13 else
14 return dts(n-1 )+(char )(‘ A ‘ +n-1 )+dts(n-1 );
15 }
C的实现方式我还不是太清楚怎么去实现,因为不能使用string这一个类来定义一个函数,可能需要自己写一个结构吧
以上是关于蓝桥杯之贪心的主要内容,如果未能解决你的问题,请参考以下文章
蓝桥杯之数论专题
蓝桥杯之FJ的字符串
蓝桥杯之K好数问题
蓝桥杯之16进制转8进制
蓝桥杯 贪心模板 _算法提高 快乐司机
蓝桥杯 ALGO-985 幸运的店家(贪心)