A:2.4
B:
思路或者想法:
已知小红的卡牌排列,想要得到小苯的卡牌排列
在最高分数的情况下得到有多少种排列方式
猜测题型:组合数学,单调队列,单调栈,优先队列,贪心?
样例
4
1 8 7 2
3 6 4 5如果我们将小的数字放到前面,比如1 2 7 8
那么小红将得到4分,小苯0分,故该思路不对
相反,我们将大的数字放到前面进行消耗,那么我们最高可以获得2分
比如 7 8 1 2
7和8移除之后,1,2不会被消耗,只有两分,再对其进行排列组合
这也是一个问题:因为对排列组合的学习理解不够深厚
所以思路便是将小苯的排列进行从大到小排序,尝试得到一个结果
但还需在某个节点进行思考,怎样得到更多的结果
C:
已AC,以下为核心代码
void solve(){
int n;cin>>n;
int tmp,maxn=-1;
vector<int>vec;
for(int i=0;i<n;i++){
cin>>tmp;
vec.push_back(tmp);
maxn=max(tmp,maxn);
}
cout<<maxn*(n-2)+vec[0]+vec[n-1]<<endl;
}希望数组中的所有数字总和尽可能大,那最好的一种情况就是将数组中的数字全部换为数组中最大的数字,但是要注意一个点,就是题中说选择下标,是开区间,也就是说可能开头和结尾处如果不是最大值那么也不能改变,需要分类讨论
答案的最大值就是maxn*(n-2)+vec[0]+vec[n-1]
E:
已AC,以下为核心代码
void solve(){
int n,k;cin>>n>>k;
vector<int>vec(n+2);
for(int i=1;i<=n;i++){
cin>>vec[i];
}
vec[n+1]=k;
vector<int>dt(n+2);
for(int i=1;i<=n+1;i++){
if(i==1){
dt[i]=vec[vec.size()-1]+vec[1];
continue;
}
dt[i]=vec[i]+vec[i-1];
}
sort(dt.begin()+1,dt.end());
// for(int i=1;i<dt.size();i++){
// cout<<dt[i]<<' ';
// }
// cout<<endl;
cout<<dt[n+1]<<endl;
}从题目中就不难得出,该万能方块从左侧插入然后从右侧挤出一个新的万能方块
这其实就是队列的一种思想,先进先出思想,当然,本题我不打算使用队列来写,
用数组模拟队列足矣。
思路:
将万能方块也放入数组中,充当队列中的一员,那么我们要得出的就是一个循环队列中,求所有相邻两项和的最大值
a1,a2,a3,k s=a1+k
k,a1,a2,a3 s=k+a3
a3,k,a1,a2 s=a3+a2
a2,a3,k,a1 s=a2+a1
将这些s存入一个数组,用sort排序即可
D:
该题有了大概思路,不过未能实现
思路的核心代码
void solve(){
int n,k;cin>>n>>k;
vector<int>vec(n+1);
int start=1;bool st=false;
int numwhite=0;
for(int i=1;i<=n;i++){
cin>>vec[i];
if(vec[i]!=0&&st==false){
start=i;st=true;
}
if(vec[i]>0) numwhite++;
}
if(k>=numwhite){
cout<<0<<endl;
return;
}
int sec=1;//未定义
k-=1;
while(1){
int next=vec[start]+start;
start=next;
if(next>=n){
break;
}
if(vec[next]==0){
if(k<0){
cout<<-1<<endl;
return;
}
for(int i=next;i<=n;i++){
if(vec[i]!=0){
next=i;
k-=1;
break;
}
}
}
cout<<sec<<" "<<next<<endl;
sec++;
}
cout<<sec<<endl;
}数字序列,每个元素都有一个颜色,ai>0即白色,ai=0即黑色
ai所对应的值表明可以穿透多少色块
比如2 0 1 0 2 0 0 1
第一个2可以穿透第一个0直接到达1的位置将其染红
2 0 1 0 2 0 0 1
但是第一个1不能穿透0使后面的2染红
那么就要利用到k,即小苯开始时至多使k个白色元素染红(特判,如果白色元素数量numwhite小于等于k,那么我们直接一开始把所有白色元素染红即可,花费0秒),每次遇到黑色元素,那么我们从这里开始就穿过去直到找到第一个不为0的数字,将其染红,花费一次k,即k--,一直搜寻到最后一个元素
这里使用了一种迭代的方法(感觉很像动态规划,不过对于动态规划的理解还需再深入),就是找到序列中第一个不为0的数字其下标作为start,然后往后延申,下一个下标next就应该是vec[start]+start,就是start表示现在位置,vec[start]表示向后移动的位移,综合得出下一个目标移动位置,然后将该坐标点作为一个新的start,即start=next,由此逐步推进
但是这里遇到的问题是对于sec,现在要解决的问题就是穿透过去之后,k-=1,相对应的sec也要变为0,因为如果要消耗k,那么就说明这个染红的点是从0秒得到的
所以,我们就要记录所有秒数,然后求得一个最大的秒数,这样就可以确保所有白色元素被染红
如果染到后面发现k<0,那么就说明不能染完所有,输出-1
F:2.4
G:2.4
H:2.4
I:2.4
J:2.4
K:
已AC,以下为核心代码
void solve(){
int n;cin>>n;
if(n==1){
cout<<"YES"<<endl;
cout<<1<<endl;
}else if(n==3){
cout<<"YES"<<endl;
cout<<"1 2 3"<<endl;
}else{
cout<<"NO"<<endl;
}
}思维题,思路感觉很简单,因为我也没推导出相应公式直接套的
如果数组长为1或者3,才有可能出现以下公式
a1*a2*a3......*an=a1+a2+a3+......+an;
数组长为1,那么不用推了
数组长为3,a1,a2,a3分别为1,2,3,这样才有可能
感觉数组再长都不会改变NO的结果了
L:
已AC,以下为核心代码
void solve(){
int n;
cin>>n;
n%=10;
if(n==1||n==3||n==7||n==9) cout<<10<<endl;
else if(n==2||n==8||n==4||n==6) cout<<5<<endl;
else if(n==5) cout<<2<<endl;
else if(n==0) cout<<1<<endl;
}如果希望n的个位为0,那么只要从它的个位入手即可
对n的个位分类讨论即可