蓝桥杯省赛训练营部分题目

蓝桥杯

链表

小王子单链表:有标号1-10的10个玩具,每次都要把喜欢的那个玩具排到最前面。

#include<iostream>
using namespace std;
struct Node
{
    int data;//数据域
	Node* next;//指针域
};
Node* head=new Node;//生成头结点
//创建过程
void init()
{
	head->next=NULL;
	for(int i=10;i>=1;i--)
    {
        Node* temp=new Node;
        temp->data=i;

        temp->next=head->next;
        head->next=temp;
    }
}
//插入操作
void insert(int x)
{
    Node* temp=new Node;
    temp->data=x;

    temp->next=head->next;
    head->next=temp;
}
//删除操作
void del(int x)
{
    Node* before=head;//before用来存放前驱结点
    for(Node* T=head->next;T!=NULL;T=T->next)//链表遍历
    {
        if(T->data==x)
        {
            before->next=T->next;
            delete T;
            return;
        }
        before=T;
    }
}
//显示操作
void show()
{
    for(Node* T=head->next;T!=NULL;T=T->next)
    {
        cout<<T->data<<" ";
    }
    cout<<endl;
}
int main()
{
    init();
    int t;
    cin>>t;
    while(t--)
    {
        int x;
        cin>>x;
        del(x);
        insert(x);
        show();
    }
}

约瑟夫环

找到第k个位置,出列处理

循环单链表

//n个人从K位置开始报数,数到m出列
//用的无头结点的尾插法 
#include<bits/stdc++.h>
using namespace std;
struct node
{
	int data;
	node* next;
 };
int main()
{
	int n,k,m;
	cin>>n>>k>>m;
	//构造链表
	node *first=new node;//头结点 
	node *p,*q;
	p=first;//保留头结点 
	first->data=1;//头结点 
	for(int i=2;i<=n;i++)
	{
		q=new node;
		q->data=i;
		p->next=q;//插入数据 
		p=p->next;//指针后移 
	}
	p->next=first;//首尾相接,构成循环链表
	p=first;
	//找到第K个位置
	for(int i=1;i<=k-1;i++)
	{
		p=p->next;
	 } 
	//只剩下一个结点的时候停止 
	 while(p!=p->next)
	 {
	 	for(int i=1;i<m-1;i++)//找到第m个结点 的前一个结点 
	 	{
	 		p=p->next;
		 }
		 q=p->next;//要出队的元素
		 cout<<q->data<<endl;
		 p->next=q->next;//从队列中出队 
		 delete q;
		 p=p->next; //后移一位 
	  } 
	  cout<<p->data<<endl;//把最后一个元素输出来 
	  return 0;
 } 

数字三角形

递推

请添加图片描述

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[110][110];
    //处理输入
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
            cin>>a[i][j];
    }
    //从后往前推,一直到a[1][1],a[i][j]=a[i][j]+max(a[i+1][j],a[i+1][j+1)
    for(int i=n-1;i>=1;i--)
    {
        for(int j=1;j<=i;j++)
        {
            a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
        }
    }
    cout<<a[1][1];
}

vector

请你设计一个程序对该问题进行解答。

众所周知在扑克牌中,有一个老掉牙的游戏叫做 2424 点,选取 44 张牌进行加减乘除,看是否能得出 2424 这个答案。

现在小蓝同学发明了一个新游戏,他从扑克牌中依次抽出6张牌,注意不是一次抽出,进行计算,看是否能够组成 4242 点,满足输出 YES,反之输出 NO

最先抽出来的牌作为第一个操作数,抽出牌做第二个操作数,运算结果再当作第一个操作数,继续进行操作。

注:除不尽的情况保留整数,而且扑克牌的四张 1010 都丢了,不会出现 1010。

请设计一个程序对该问题进行解答。

输入描述

输出仅一行包含 66 个字符。

保证字符 ∈ 3 4 5 6 7 8 9 10 J Q K A 2

输出描述

若给出到字符能够组成 4242 点 , 满足输出 YES,反之输出 NO

输入输出样例

示例

输入

K A Q 6 2 3 

输出

YES

样例说明

  • K× A=K即13×1=13

  • 13/12=1保留整数

  • 1+6=7

  • 7*2=14

  • 14*3=42

#include<bits/stdc++.h>
using namespace std;
//加减乘除都算一遍,出现42就是yes
//两个操作数运算

int main()
{
    char a;
    int b[10];
    for(int i=1;i<=6;i++)
    {
        cin>>a;
        if(a>='2'&&a<='9')//a是一个字符呀,没有10
        {
            b[i]=a-'0';
        }
         else if(a=='A')
        {
            b[i]=1;
        }
        else if(a=='J')
            b[i]=11;
        else  if(a=='Q')
            b[i]=12;
        else if(a=='K')
            b[i]=13;
    }
    //分别将加减乘除的结果保留出来,再进行下一个加减乘除
    vector<int> ans[10];//一个二维数组,用来存放每一个阶段的值
    //ans[0][0]=b[1];是错误的写法
    ans[0].push_back(b[1]);
    for(int i=1;i<=5;i++)//一共有五个阶段
    {
        for(int j=0;j<ans[i-1].size();j++)//主要利用的是size(),用前面乘出来的数一次与后面的数做运算
        {
            ans[i].push_back(ans[i-1][j]+b[i+1]);
            ans[i].push_back(ans[i-1][j]-b[i+1]);
            ans[i].push_back(ans[i-1][j]*b[i+1]);
            ans[i].push_back(ans[i-1][j]/b[i+1]);
        }
    }
    int flag=0;
    for(int i=0;i<ans[5].size();i++)
    {
        if(ans[5][i]==42)
            flag=1;
    }
    if(flag==1)
        cout<<"YES";
    else
        cout<<"NO";

}

组合数

从n个学生中,选m个人参加比赛,列出组成的组合

#include<bits/stdc++.h>
using namespace std;
string a[20];
vector<string> name;
vector<string> ans;
vector<int> chosen;
int n,m;
void calc(int x)
{
    if(chosen.size()>m||chosen.size()+(n-x+1)<m)//选的人数多了或者选不够了
        return;
    if(x==n+1)//如果前面的都已经试过了
    {
        string ansTem="";
        for(int i=0;i<chosen.size();i++)
        {
            ansTem+=name[chosen[i]-1]+" ";
        }
        ans.push_back(ansTem);
        return;
    }
    calc(x+1);

    chosen.push_back(x);
    calc(x+1);

    chosen.pop_back();//消除痕迹
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        string s;
        cin>>s;
        name.push_back(s);//把名字存在vector里
    }
    calc(1);
    for(int i=ans.size()-1;i>=0;i--)
    {
        cout<<ans[i]<<endl;
    }
}

排列数

n个人,写出他们座位的排列结果

#include<bits/stdc++.h>
using namespace std;
int n;
string name[20];
int order[20];
bool chosen[20];
void calc(int k)
{
    if(k==n+1)
  {
        for(int i=1;i<=n;i++)
        {
            cout<<name[order[i]-1]<<" ";
        }
        puts("");
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(chosen[i])
            continue;
        order[k]=i;
        chosen[i]=1;
        chosen[i]=1;
        calc(k+1);
        chosen[i]=0;
        order[k]=0;
    }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>name[i];
    }
    calc(1);
}

二分答案

分巧克力

蓝桥杯省赛 14 天夺奖冲刺营 - 练一练「分巧克力」 - 蓝桥云课 (lanqiao.cn)

暴力解题也过了

#include<bits/stdc++.h>
using namespace std;
//二分答案问题
int  n,k;
int h[100010],w[100010];
bool fun(int x)//看看x符不符合要求
{
    int sum=0;
    int t;
    for(int i=1;i<=n;i++)
    {
        sum+=(h[i]/x)*(w[i]/x);
    }
    if(sum<k)
    {
        return true;
    }
    return false;
}
int main()
{
    cin>>n>>k;
    int x=0;
    int m;
    for(int i=1;i<=n;i++)
    {
        cin>>h[i]>>w[i];
        m=max(h[i],w[i]);
        x=max(m,x);
    }
    while(fun(x))//如果不符合条件,就进行下一次判断,直到遇到符合条件的
    {
        x--;
    }
    cout<<x;
}

二分法

#include<bits/stdc++.h>
using namespace std;
//二分答案问题
int  n,k;
int h[100010],w[100010];
bool fun(int x)//看看x符不符合要求
{
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=(h[i]/x)*(w[i]/x);
        if(sum>=k)
            return true;
    }
    return false;
}
int main()
{
    cin>>n>>k;
    int x=0;
    int m;
    for(int i=1;i<=n;i++)
    {
        cin>>h[i]>>w[i];
        m=max(h[i],w[i]);
        x=max(m,x);
    }
    int high=x;//二分查找的上界
    int low=1;//下界
    int mid=0;
    while(low<high)
    {
        mid=(low+high+1)/2;//把区间分为了[l,mid-1][mid,r]
        if(fun(mid))//如果Mid是符合条件的,我需要找的是最大值,我要更新下界,再试试更大的数满不满足条件
            low=mid;
        else//如果mid不满足条件,说明我分块数少了,我要更新上界,找到那个合适的数
            high=mid-1;
    }
    cout<<low;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
double n;
int m;
bool judge(double a)
{
    double ans=1;
    int t=m;
    while(t--)
    {
        ans=ans*a;
    }
    if(ans>=n)
        return true;
    else
        return false;
}
int main()
{
    cin>>n>>m;//求m次根下n的值,保留小数点后七位
    double low=1;
    double high=n;
    double mid;
    while(high-low>1e-9)
    {
        mid=(low+high)/2;

        if(judge(mid))//现在测试的这个值比n大了,应该小一点
            high=mid;
        else
            low=mid;
    }
    printf("%.7f",mid);
}

贪心

小B的宿舍

蓝桥杯省赛 14 天夺奖冲刺营 - 练一练「小 B 的宿舍」 - 蓝桥云课 (lanqiao.cn)

不难,就是没看对题…

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        int s,t;
        int m[500];
        memset(m,0,sizeof(m));
        for(int i=0;i<n;i++)
        {
            cin>>s>>t;
            s=(s+1)/2;
            t=(t+1)/2;
            for(int j=s;j<=t;j++)
            {
                 m[j]++;
            }

        }
        int maxm=0;
    for(int i=1;i<=200;i++)
    {
        maxm=max(maxm,m[i]);
    }
    cout<<(maxm+1)/2*10<<endl;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HHHᕙ(`▿´)ᕗ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值