蓝桥杯
链表
小王子单链表:有标号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;
}
}