寄了,300元买了两个脆脆鲨和一瓶水哈哈
可以在下面民间网站提交测试
蓝桥杯真题(更新至2023年) - 编程题库 - C语言网 (dotcpp.com)
教训 :(1)直接输出骗样例的别忘了先把题目的输入写上
(2)读清楚题目要求 (3)一定要return 0 ;啊啊啊啊
(4)devc++的输入窗口可以从属性哪里改成可复制(傻傻的自己敲案例)
(5)把思路想好了再动手,(别白白浪费时间)
(6)别忘开long long
下面是某大佬讲解的视频,讲的很清楚
【问题描述】
小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的
范围之内。数组中的元素从左至右如下所示:
5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2
7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1
0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3
现在他想要从这个数组中寻找一些满足以下条件的子序列:
1. 子序列的长度为 8;
2. 这个子序列可以按照下标顺序组成一个 yyyymmdd 格式的日期,并且
要求这个日期是 2023 年中的某一天的日期,例如 20230902,20231223。
yyyy 表示年份,mm 表示月份,dd 表示天数,当月份或者天数的长度只
有一位时需要一个前导零补充。
请你帮小蓝计算下按上述条件一共能找到多少个不同 的 2023 年的日期。
对于相同的日期你只需要统计一次即可。
#include
using namespace std;
const int MAX=2e5+10;
int arr[MAX],ans;
int months[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
/*dfs选入的数只需要判断56位月份对应的天数是否合理就行了 (1234 5678)*/
setmyset; //每一种日期只加入一次,因此用set去重
bool check(int data)
{
if(myset.count(data))return false;
int month=(data/100%10+data/1000%10*10); //提取月份 先除保留高位,再%10取末位
if(month>12||month==0)return false;
int days=data%10+data/10%10*10; //提取天数
//注意这里月数和天数为0的情况
myset.insert(data);
if(days<=months[month]&&days>0)return true;
return false;
}
void dfs (int x,int index,int data)
{//x表示遍历到100个数哪一个的下标 ,index为选中了几个数的(0-8), data为选中index个数组成的日期
if(x>=100)return ;
if(index==8)
{
if(check(data))//符合要求就加入答案
ans++;
return ;
}
/*先把确定的几位剪枝*/
if((index==0&&arr[x]==2)||(index==1&&arr[x]==0)||(index==2&&arr[x]==2)||(index==3&&arr[x]==3))
{//前四位:data第1-4位必须是2013
dfs(x+1,index+1,data*10+arr[x]);
}
else if((index==4&&(arr[x]==0||arr[x]==1))||(index==5)||(index==6&&arr[x]>=0&&arr[x]<=3)||index==7)
{//后四位:第四位月份首位必须是0/1 第五位随便 第六位那一天首位必须是0-3 第七位随便
dfs(x+1,index+1,data*10+arr[x]);
}
dfs(x+1,index,data);//不加入arr[x] (可能为上面不符合条件的 或回溯回来的)
}
int main()
{
for(int i=0;i<100;i++)
cin>>arr[i];
dfs(0,0,0);
cout<<"----------\n";
cout<
#include
using namespace std;
const int MAX=2e5+10;
int main()
{
double n=23333333;
double ans=11625907.5798;
double eps=1e-4;//浮点数比较方式:定义一个误差允许范围
for(int i=0;i<23333333/2;i++)
{
int j=n-i;
double shang=-1.0*i*i/n*log2(i/n)-1.0*j*j/n*log2(j/n);
//注意这两个1.0一定要乘上 (好像是不乘精度降低)
if(fabs(shang-ans)
53 2
59 2
#include
using namespace std;
const int MAX=2e5+10;
int arr[MAX],output[MAX],n;
bool check(int mid)
{
for(int i=0;ioutput[i])return false;
}
return true;
}
int main()
{
int resmax=INT_MAX;
cin>>n;
for(int i=0;i>arr[i]>>output[i];
resmax=min(resmax,arr[i]/output[i]);
//最大值就是arr[i]/output[i]的最小值
}
int left=0,right=resmax;
while(left
#include
using namespace std;
const int MAX=2e5+10;
struct Plane
{
int T,D,L;
int end;//飞机最晚下降时间
}plane[MAX];
int n;
bool cmp(Plane p1,Plane p2)
{
return p1.end>t;
while(t--)
{
cin>>n;
for(int i=0;i>T>>D>>L;
plane[i].T=T;
plane[i].D=D;
plane[i].L=L;
plane[i].end=T+D;
}
int flag=1;
sort(plane,plane+n,cmp);
for(int i=0;i
#include
using namespace std;
const int MAX=2e5+10;
int T[MAX],D[MAX],L[MAX],used[MAX];
int flag,n;
/*curTime可降落时间(上一辆降落完毕时间),num是已降落数量
本题采用N<=10,且类似全排列(排列每辆飞机降落顺序),可采用回溯
*/
void backtracking(int curTime,int num)
{//枚举所有排列,能满足情况返回
if(num==n||flag)
{
flag=1;return ;
}
for(int i=0;iT[i]+D[i])continue; //这一辆降不了(到这一辆的截至时间上一辆还没降落完)
used[i]=1;
backtracking(max(T[i],curTime)+L[i],num+1);
//有可能curTime时间i还每到,所以i降落时间为 max(T[i],curTime)+L[i]
used[i]=0;
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
for(int i=0;i>T[i]>>D[i]>>L[i];
}
flag=0;
memset(used,0,n*4);
backtracking(0,0);
if(flag)cout<<"YES\n";
else cout<<"NO\n";
}
}
#include
using namespace std;
const int MAX=2e5+10;
int n,dp[10];
int main()
{
cin>>n;
/*dp[d]为以d这个数为结尾的最长接龙序列 (因为这个题全都是数字)
所以对于每一个数 首部为x,尾部为y,dp[y]=max(dp[y],dp[x]+1)
不接到前面 接到前面
我用的类似子序列dp,只能ac五分之一,这个真的秀 ,跳出了序列,直接对数字进行dp
则最短删除长度为总长度减去最长接龙长度
*/
int maxlen=0;
for(int i=0;i>data;
y=data%10;
while(data)
{//获取data高位 与低位
if(data/10==0)x=data;
data/=10;
}
dp[y]=max(dp[y],dp[x]+1);
maxlen=max(maxlen,dp[y]);
}
cout<
#include
using namespace std;
const int MAX=2e5+10;
int m,n,vis[55][55],used[55][55];
char graph[55][55];
int dx[]={-1,1,0,0,1,1,-1,-1};
int dy[]={0,0,1,-1,1,-1,1,-1};//标定八个方向
void dfs(int i,int j)
{
vis[i][j]=1;
for(int dim=0;dim<4;dim++)
{
int x=i+dx[dim],y=j+dy[dim];
if(x<0||x>=m||y<0||y>=n)continue;
if(graph[x][y]=='0'||vis[x][y])continue;
vis[x][y]=1;
dfs(x,y);
}
}
void init_used()
{
for(int i=0;i=m||y<0||y>=n)continue;
if(graph[x][y]!='0'||used[x][y])continue;
used[x][y]=1;
if(dfs_out(x,y))return true;//逃出去了返回
}
return false;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>m>>n;
for(int i=0;i>graph[i][j];
vis[i][j]=0;
}
}
int ans=0;
for(int i=0;i
#include
using namespace std;
const int MAX=5e5+10;
int k,n,sum[MAX];
string s;
int main()
{
/*本题使用后缀和 用sum记录[i,n)中c2的个数
则从头遍历每一个c1,此c1产生的合规子串个数就是c1左边加上k-1,后面c1的个数
*/
char c1,c2;
cin>>k>>s>>c1>>c2;
vectors1,s2;
n=s.size();
for(int i=n-1;i>=k-1;i--)
{//sum[i]为从[i,n)有多少个c2
if(s[i]==c2)sum[i]=sum[i+1]+1;
else sum[i]=sum[i+1];
}
long long ans=0;
for(int i=0;i=MAX)temp=MAX-1;
ans+=sum[temp];
}
}
cout<
#include
using namespace std;
#define val first
#define index second
const int MAX=5e5+10;
typedef long long ll;
typedef pair PII;
priority_queuemyque;
ll arr[MAX];
int pre[MAX],nxt[MAX];
int n;
int main()
{
/*用两个数组模拟双向链表 pre[i]为i结点上一个结点下标, nxt[i]为i下一个
用优先队列维护最小值
*/
int k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>arr[i];
pre[i]=i-1;
nxt[i]=i+1;
myque.push({-arr[i],-i});//不想写cmp,所以插入负的val,则最大堆顶就是负的最大值,即最小值
}
pre[1]=-1;
nxt[n]=-1;
for(int j=0;j
LCA 板子
#include
using namespace std;
const int MAX=5e5+10;
vectore[MAX],w[MAX]; //用二维vector模拟邻接表存储树
int fa[MAX][20]; //fa[u][j]是u向上跳2^j步到达的结点 最大20是因为该数据范围的树最多2^20层
int deep[MAX];//存储每个结点的深度
int vis[MAX];
int N,M,S;
//求lca之前dfs一遍得到fa,deep表 ,dfs由上(father)向下(son)推,每次沿一条路径走到底
void dfs(int u,int father)
{//father是u的父节点
if(vis[u])return;
vis[u]=1;
fa[u][0]=father;
deep[u]=deep[father]+1;//更新深度
for(int i=1;i<=19;i++)
{//最多跳2^19步
fa[u][i]=fa[fa[u][i-1]][i-1]; //先跳一半到fa[u][i-1]再跳一半到u上面2^i
}
for(int v:e[u])
{//往下在求u的所有孩子结点v
if(u!=v)dfs(v,u);
}
}
/*返回u,v的最近公共祖先lca ,先把u,v跳到同一层,然后一起往上跳 */
int lca(int u,int v)
{
if(deep[u]=0;i--)
{//按二进制与十进制转化来跳 (注意要从大到小跳) 25=16+8+1
if(deep[fa[u][i]]>=deep[v])u=fa[u][i];
}
if(u==v)return u;//跳完后相等直接返回
for(int i=19;i>=0;i--)
{//也是按二/十转化来挑 最后二者停在lca的下一层
if(fa[u][i]!=fa[v][i])
{//注意不相等才跳 (因为跳大了可能不是最近的)
u=fa[u][i],v=fa[v][i];
}
}
return fa[u][0];//因为上面停在lca下一层,所以返回u的上一层即为lca
}
int main()
{
cin>>N>>M>>S;
for(int i=1;i>u>>v;
e[u].push_back(v);
e[v].push_back(u);
w[u].push_back(v);
w[v].push_back(u);
}
dfs(S,0);
for(int i=0;i>u>>v;
cout<
#include
using namespace std;
const int MAX=5e5+10;
vectore[MAX],w[MAX]; //用二维vector模拟邻接表存储树
int fa[MAX][20]; //fa[u][j]是u向上跳2^j步到达的结点 最大20是因为该数据范围的树最多2^20层
int deep[MAX];//存储每个结点的深度
long long dis[MAX]; //记录每个点到根节点的距离
int A[MAX]; //存放游览路径
int N,K;
//求lca之前dfs一遍得到fa,deep表 ,dfs由上(father)向下(son)推,每次沿一条路径走到底
void dfs(int u,int father)
{//father是u的父节点
fa[u][0]=father;
deep[u]=deep[father]+1;//更新深度
for(int i=1;i<=19;i++)
{//最多跳2^19步
fa[u][i]=fa[fa[u][i-1]][i-1]; //先跳一半到fa[u][i-1]再跳一半到u上面2^i
}
for(int i=0;i=0;i--)
{//按二进制与十进制转化来跳 (注意要从大到小跳) 25=16+8+1
if(deep[fa[u][i]]>=deep[v])u=fa[u][i];
}
if(u==v)return u;//跳完后相等直接返回
for(int i=19;i>=0;i--)
{//也是按二/十转化来挑 最后二者停在lca的下一层
if(fa[u][i]!=fa[v][i])
{//注意不相等才跳 (因为跳大了可能不是最近的)
u=fa[u][i],v=fa[v][i];
}
}
return fa[u][0];//因为上面停在lca下一层,所以返回u的上一层即为lca
}
long long path_uv(int u,int v)
{//u到v距离为 u到根+v到根-2倍的lca到根 (画图看看)
if(!u||!v)return 0;//因为v->0应该为0
return dis[u]+dis[v]-2*dis[lca(u,v)];
}
int main()
{
cin>>N>>K;
for(int i=1;i>u>>v>>W;
e[u].push_back(v);
w[u].push_back(W);
e[v].push_back(u);
w[v].push_back(W);
}
dfs(1,0);
long long sum=0;//储存未跳过的游览路径之和
for(int i=1;i<=K;i++)
{
cin>>A[i];
sum+=path_uv(A[i-1],A[i]);
}
for(int i=1;i<=K;i++)
{//则却掉A[i]点路径之和为:总路径-A[i-1]到A[i] -A[i]到A[i+1] +A[i-1]到A[i+1],即从A[i-1]到A[i+1]不经过A[i]
cout<
#include
using namespace std;
const int N = 1e5 + 10, M = 18;
vector> g[N];
int dep[N], f[N][20], cnt[N], w[N];
void init(int u, int fa) {
dep[u] = dep[fa] + 1, f[u][0] = fa;
for (int i = 1; (1 << i) <= dep[u]; i ++) f[u][i] = f[f[u][i - 1]][i - 1];
for (auto &e : g[u]) {
if (e.first != fa) init(e.first, u), w[e.first] = e.second;
}
}
int lca(int a, int b) {
if (dep[a] < dep[b]) swap(a, b);
for (int i = M; i >= 0; i --) {
if (dep[f[a][i]] >= dep[b]) a = f[a][i];
if (a == b) return a;
}
for (int i = M; i >= 0; i --) {
if (f[a][i] != f[b][i]) a = f[a][i], b = f[b][i];
}
return f[a][0];
}
void add(int a, int b) {
int LCA = lca(a, b);
cnt[a] ++, cnt[b] ++, cnt[LCA] -= 2;
}
void dfs(int u, int fa) {
for (auto &e : g[u]) {
if (e.first != fa)
dfs(e.first, u), cnt[u] += cnt[e.first];
}
}
int main () {
int n, m; cin >> n >> m;
for (int i = 1; i < n; i ++) {
int a, b; cin >> a >> b;
g[a].push_back({b, i}), g[b].push_back({a, i});
}
init(1, 0);
for (int i = 0; i < m; i ++) {
int a, b; cin >> a >> b;
add(a, b);
}
dfs(1, 0);
int res = -1;
for (int i = 1; i <= n; i ++)
if (cnt[i] == m && (w[i] > res)) res = w[i];
cout << res << endl;
return 0;
}