A:一二五八

题目描述

X星球有一个部落一直沿用着一套古老的货币。这套货币一共有四种面值,分别是1星、2星、5星和8星。X星人决定携带总金额为N星的货币来进行一次环球旅行,因为需要携带的物品实在太多太多,他希望携带的货币数量能够最少。
你能否编写一个程序帮助X星人计算出需要携带的最少货币数量?

输入

单组输入。每组一个正整数N,表示X星人携带的总金额。(N<=10^3)

输出

输出X星人最少需要携带的货币数量。

  • 贪心
  • 能用多少8星就用多少
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
int main(){int n;scanf("%d",&n);int ans=n/8;n%=8;if(n==1||n==2||n==5)ans++;else if(n)ans+=2;printf("%d\n",ans);return 0;
}

B:和为1

题目描述

给出n个正整数,这n个正整数中可能存在一些相同的数。现在从这n个数中选取m个正整数,分别记为X1、X2、…、Xm,使得这m个数满足如下公式:
1/X1 + 1/X2 + … + 1/Xm = 1
请问存在多少种不同的数字组合可以使得上述公式得以成立?

输入

单组输入。
第1行输入一个正整数n,表示输入的正整数个数。(n<=100)
第2行输入n个正整数,两两之间用空格隔开。

输出

输出满足要求的组合个数。如果一个组合都不存在,则输出“No solution!”。

  • 搜索
  • 找到一组和为1的数很容易,直接搜索,但是答案很多重复的组,所以要加判重
  • 搜索:分为分子,分母,每次选的数与当前选的分母求出最小公倍数组成新的分母,再求出分子,继续搜索
  • 判重:先对数组从小到大排序,每一组选的数用字符串s连接,在记录答案时,只记录第一次出现的答案字符串
  • 最后一发AC91%,改了好久的判重
#include<bits/stdc++.h>
using namespace std;
int a[105];
int ans,n;
map<string,bool>vis;
int gcd(int x,int y){//最大公约数return y==0 ? x:gcd(y,x%y);
}
int lcm(int x,int y){//最小公倍数return x*y/gcd(x,y);
}
void dfs(int fz,int fm,string s,int pos){if(fz==fm&&fz){if(!vis[s])//判重ans++;vis[s]=1;return ;}if(pos>n)return ;if(fz==0)dfs(1,a[pos],s+to_string(a[pos]),pos+1);else {int m=lcm(a[pos],fm);int z=(m/a[pos])+(m/fm)*fz;int g=gcd(m,z);dfs(z/g,m/g,s+to_string(a[pos]),pos+1);}dfs(fz,fm,s,pos+1);}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);sort(a+1,a+1+n);dfs(0,0,"",1);if(ans)printf("%d\n",ans);else printf("No solution!\n");return 0;
}

C:素数拆分

题目描述

如果将一个n(n>=2)位的素数拆分成两部分,其中高m位是一个素数,低(n-m)位也是一个素数,那么这个数称为可拆分素数。
例如113,它可以拆成两部分,高两位11是一个素数,低一位3也是一个素数,因此113是一个可拆分素数。
现在输入两个正整数M和N(M<N),请编写一个程序计算M到N之间有多少个可拆分素数(可以包含M和N)。

输入

单组输入。
输入两个正整数M和N(10<=M<N<=10^6)。

输出

输出M和N之间可拆分素数的个数(包含M和N)。

  • 枚举
  • 先筛法求出2~m之间的素数,然后枚举n-m之间的数,判断是否是可拆分素数
  • 判断素数是否可拆分也是枚举,枚举前后各多少个数
  • 代码可能比我说的容易看懂
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
int n,m;
bool isprime[1000005];
void prime(){//筛法求素数int i,j;isprime[0] = false;isprime[1] = false;isprime[2] = true;for(i=3; i<=m; i++) {isprime[i++] = true;isprime[i] = false;}int ma = sqrt(m);for(i=3; i<=ma; i++){if(isprime[i]) {for(j=i+i; j <= m; j+=i)isprime[j] = false;}}
}
bool check(int i){//判断一个素数是否可拆分int x=10;while(x<=i){if(isprime[i/x]&&isprime[i%x])return 1;x*=10;}return 0;
}
void cnt(){int ans=0;for(int i=n;i<=m;i++){if(isprime[i]&&check(i)){ans++;}}printf("%d\n",ans);
}
int main(){scanf("%d%d",&n,&m);prime();cnt();return 0;
}

D:空心圆柱

题目描述

小米同学用薄纸片卷了N个空心的小圆柱,他想把一些小的空心圆柱嵌到大的空心圆柱里面。
已知每一个空心圆柱的底面半径,在不考虑薄纸片本身厚度的情况下,请问这些空心圆柱最多可以嵌套多少层?

输入

单组输入。
第1行输入一个正整数N表示空心小圆柱的总数量。(N<=10^3)
第2行输入N个正数(有整数也有小数,最多不超过八位小数),表示N个空心小圆柱底面半径。

输出

输出最多可以嵌套的空心圆柱的数量。

  • 水题
  • 判断多少个不同的半径的圆柱就行
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
int n;
double a[1005];
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lf",&a[i]);}sort(a+1,a+1+n);int ans=0;for(int i=1;i<=n;i++){if(a[i]!=a[i-1])ans++;}printf("%d\n",ans);return 0;
}

E:营救行动

题目描述

X星卫士接到了一个紧急任务。大BOSS被困Y星的地狱迷宫,X星卫士必须携带“时空转移丸”尽快前往营救。
Y星的地狱迷宫是一个有M*N个小房间构成的矩形结构,迷宫中的小房间一共有M行,每一行有N列。
迷宫的入口为第1行第1列,标记为“S”,大BOSS被困的位置标记为“B”。
X星卫士通过每个普通小房间的时间均为1分钟。但是在这个迷宫中,有一些房间中设置了机关,一共包含三类不同的机关,分别是:死亡陷阱、延时陷阱和定向陷阱。死亡陷阱是不能进入的房间,一旦进入将万劫不复,营救失败;延时陷阱中布满死亡光线,需要3分钟时间才能够顺利通过;定向陷阱中设有一个定向诱导装置,进入该房间者将丧失转向功能(只在该房间中丧失),只能沿着直线行进,例如从左边进入只能从右边出来,从上面进入只能从下面出来,不过通过时间还是1分钟。
对于一个给定的地狱迷宫地图,请问最少需要多少时间(分钟)才能够营救到大BOSS(进入BOSS房间不消耗步数)?

输入

单组输入。
第1行输入两个正整数M和N,分别表示迷宫矩阵的行和列。(M<=103,N<=103)
第2行到第M+1行,每行N列,对应一个二维字符矩阵,用于表示地狱迷宫。
在字符矩阵中,“S”表示迷宫入口,“B”表示大BOSS被困的位置,“0”表示可以正常通过的房间(通过时间为1分钟),“#”表示死亡陷阱,“*”表示延时陷阱,“@”表示定向陷阱。

输出

X星卫士营救到大BOSS所需最少时间(单位:分钟);如果不能营救成功,则输出“Failure"。

  • 搜索
  • 在矩阵上的搜索,关于搜索强推我这篇博客 搜索专题:DFS
  • 这里是最短路模板,所以用bfs快一点,唯一要注意的就是@情况,是要延同一个方向一直走,直到走到一个不为@的地方
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
int d[][2]={0,1,1,0,0,-1,-1,0};
int dis[1005][1005];
char a[1005][1005];
struct node{int x,y;int ans;bool operator <(const node &q)const{return ans>q.ans;}
};
int ans;
bool check(int x,int y){if(x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]!='#')return 1;return 0;
}
void bfs(){priority_queue<node>q;q.push({1,1,0});while(!q.empty()){node k=q.top();q.pop();if(a[k.x][k.y]=='B'){ans=k.ans-1;return ;}if(dis[k.x][k.y])continue;dis[k.x][k.y]=1;for(int i=0;i<4;i++){int x=k.x+d[i][0];int y=k.y+d[i][1];if(check(x,y)){if(a[x][y]=='0'||a[x][y]=='B')q.push({x,y,k.ans+1});else if(a[x][y]=='*')q.push({x,y,k.ans+3});else if(a[x][y]=='@'){int res=k.ans;while(check(x,y)&&a[x][y]=='@'){dis[x][y]=1;x+=d[i][0];y+=d[i][1];res++;}if(check(x,y)){if(a[x][y]=='0'||a[x][y]=='B')q.push({x,y,res+1});else if(a[x][y]=='*')q.push({x,y,res+3});}}}}}return ;
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%s",a[i]+1);}bfs();if(ans)printf("%d\n",ans);else puts("Failure");return 0;
}

F:a碟的微机

题目描述

a碟最近刚考完微机,他觉得这门课学的太痛苦了,于是想出了一些好(wu)玩(liao)的题目,有一段数据在地址线上串行传送(将数据分解成二进制位用一条信号线,一位一位顺序传送的方式)。a碟突发奇想(乱想),将二进制位的0当作“(”,1当作“)”,如果一串数据中的"01"完全匹配(例如01, 0011, 001011),则输出“Good”,若不是完全匹配(例如001,10,0111),则输出"Bad" 。
现在给你一段数据长度为n的串s(n<=1e5),请你判断这段数据是否满足上述定义?

输入

输入一串数据串s,其长度<=1e5

输出

如果该数据串中的"01"完全匹配,则输出"Good",否则输出"Bad"

  • 模拟
  • 就是一个括号匹配,堆栈模拟一下就好了,也比较水
#include<bits/stdc++.h>
#define ll long long
using namespace std;
bool cmp(string s){stack<char>st;for(int i=0;i<s.size();i++){if(s[i]=='1'){if(!st.empty())st.pop();else return 0;}else{st.push(s[i]);}}if(st.empty())return 1;else return 0;
}
int main(){string s;cin>>s;if(cmp(s))puts("Good");else puts("Bad");return 0;
}

G:a碟的备忘录

题目描述

a碟本学期学习了安卓开发,他的同学ph经常忘记事情,于是他想做一个简单的备忘录帮助ph。
他希望他的备忘录包含以下功能:
1、向备忘录插入字符串 s(英文字符)
2、删除备忘录最后k个字符(保证不为空串)
3、输出备忘录第k个字符(保证不为空串)
4、撤销最近的1或2操作,使备忘录回到1(或者2)操作之前的状态
可是a碟琢磨了半天还是做不来,聪明的你能解决a碟的问题,帮助ph吗?

输入

第一行输入一个整数t,代表总的操作数量
以下t行每行描述了一个操作,每行以一个整数n开始(1 <= n <= 4)。
n表示上述问题陈述中定义的操作类型。 如果操作需要参数,则后跟空格分隔的参数。
题目保证所有操作均合法
1 <= t <= 10^6
1 <= k <= |记事本内容长度|
每个测试数据中s的总长度 <= 10^6

输出

只有操作3需要输出结果,每行以换行符结束。

  • 模拟
  • 直接用字符串模拟(这个不难啊,为啥没啥人做,难道是我的开题顺序影响了大家做题 )
#include<bits/stdc++.h>
using namespace std;
#define ll long long
string s2[1000005];int main(){int n;cin>>n;int d,k;string s1,str="";int pos=1;for(int i=1;i<=n;i++){cin>>d;if(d==1){cin>>s1;s2[pos++]=str;str+=s1;}else if(d==2){cin>>k;s2[pos++]=str;str=str.substr(0,str.size()-k);}else if(d==3){cin>>k;cout<<str[k-1]<<endl;}else {str=s2[--pos];}}return 0;}

H:X星人的密码

题目描述

聪明的X星人决定向在外太空的同伴发送一封非常非常重要的文件,该文件需要输入一个特殊的密码才能够打开。
这个特殊的密码是一串数字,这串数字密码需要通过解析一个包含很多正整数的文件才能够得到。
数字密码由三部分组成,这三部分对应三个正整数:第1部分是文件中所包含的最大正整数,第2部分是文件的正整数序列中所包含的最长单调递减子序列的长度,第3部分是文件中所包含的最小正整数。如果你得到了这三个部分,它们连接而成得到的数字字符串就是破解文件所需的密码。
X星人正在寻求你的帮助,你需要编写一个程序帮助他提取文件中蕴含的密码。

输入

单组输入。
第1行输入一个正整数N,表示文件中的正整数个数。(N<=1000)
第2行输入N个正整数,两两之间用空格隔开。最大正整数不超过10^6。

输出
输出文件中蕴含的数字密码。

  • 最长单调递减子序列的长度,将数组倒序就相当于最长上升子序列长度
  • 堆栈模拟,因为这个好记
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
int a[1005];
int n;
int lis(){reverse(a+1,a+1+n);vector<int>stk;stk.push_back(a[1]);for (int i = 2; i<=n; ++i) {if (a[i] > stk.back())stk.push_back(a[i]);else*lower_bound(stk.begin(), stk.end(), a[i]) = a[i];}return stk.size();
}
int main(){while(~scanf("%d",&n)){int ma=-INF,mi=INF;for(int i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]>ma)ma=a[i];if(a[i]<mi)mi=a[i];}printf("%d%d%d\n",ma,lis(),mi);}return 0;
}

I:重复DNA子片段

题目描述

给定一段由A、G、C和T这四种字符组成的DNA片段。
请编写一个程序计算该DNA片段中所包含的最长且不重叠的重复DNA子片段的长度。
例如:如果输入是“AAAAA”,则最长且不重叠的重复DNA子片段的长度为2,因为对应的不重叠最长重复子片段是“AA”。

输入

单组输入。
输入一段由A、G、C和T这四种字符组成的DNA片段。(1<=长度<=3000)

输出

输出最长且不重叠的重复DNA子片段的长度。

  • 字符串dp
  • 注意重复的字符串不能有重叠
#include<bits/stdc++.h>
using namespace std;
int dp[3005][3005];
int main(){string s;int ans=0;cin>>s;for(int i=1;i<=s.size();i++){for(int j=1;j<=s.size();j++){if(i!=j&&s[i-1]==s[j-1]){dp[i][j] = dp[i-1][j-1]+1;if(dp[i][j]>ans&&ans<abs(i-j))ans=dp[i][j];}}}cout<<ans<<endl;return 0;
}

2022年寒假训练赛第3场相关推荐

  1. 2022年寒假训练赛第6场

    A: 数字排序 题目描述 给定n个正整数,每个正整数均不超过10000,请编写一个程序统计每个整数出现的次数,并按照出现次数从多到少的顺序输出. 输入 单组输入,每组两行. 第1行包含一个正整数n,n ...

  2. 2022年寒假训练赛第5场

    A:三英战吕布 题目描述 程序员Kimi同学这几天在看<三国演义>.今天他看到了"三英战吕布"这一回. 话说在虎牢关前,张飞首先单独战吕布,几十个回合不分输赢:随后关羽 ...

  3. 2022年寒假训练赛(2020级)题解

    文章目录 出题人 A<关于508的门老是被反锁这件事> 思路 AC代码 B 昆虫关系 思路1:带权并查集 AC代码 思路2:种类并查集 AC代码2 思路3:二分图染色 AC代码3 C 谁输 ...

  4. 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FFT)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FF ...

  5. 19级算法训练赛第七场

    19级算法训练赛第七场 传送门:https://vjudge.net/contest/362412#problem/J A - 程序设计:合并数字 蒜头君得到了 n 个数,他想对这些数进行下面这样的操 ...

  6. 2021年度训练联盟热身训练赛第五场

    2021年度训练联盟热身训练赛第五场 链接:https://ac.nowcoder.com/acm/contest/13926 A Binary Seating #include<bits/st ...

  7. 2021年度训练联盟热身训练赛第八场

    目录 2021年度训练联盟热身训练赛第八场 A-Fire on Field 题意 思路 代码 B-Gene Tree 题意 思路 代码 I-Thread Knots 题意 思路 代码 J-Triang ...

  8. 【2022 省选训练赛 Contest 17 A】字符串游戏(结论)

    字符串游戏 题目链接:2022 省选训练赛 Contest 17 A 题目大意 有一个字符串一开始是空的,两个人轮流操作在任意位置插入 0/1. 然后给你一个串 s,先手目标是使得 s 是字符串的子串 ...

  9. 2021UPC个人训练赛第47场

    个人训练赛第47场 A: 加工零件(最短路) 问题 A: 加工零件时间限制: 1 Sec 内存限制: 128 MB 题目描述 凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神 ...

最新文章

  1. pytorch maxpool和卷积尺寸问题
  2. 用TensorFlow和TensorBoard从零开始构建ConvNet(CNN)
  3. vim 编辑器的快捷键
  4. 堂妹问的一道暑假作业题,难住985的家长
  5. hp服务器装xp系统,教你惠普笔记本一键装xp系统的方法
  6. EDG夺冠!每个队员获赠一套房:背后老板成最大赢家
  7. matlab搭配循环的函数按列将生成的数据写入文件
  8. qt使用QProcess实现进程通信
  9. PhotoShop大师之路视频
  10. bubblesort java,算法bubbleSort()
  11. CImageList用法介绍 (zz)
  12. ROS智能车自主导航roslaunch racecar_gazebo racecar_runway_navigation.launch报错
  13. 大数据论文_02_MapReduce(个人总结)
  14. 分组转发和路由选择基础
  15. 【复】从0到1的 selenium 爬虫经历
  16. 红日安全 ATT&CK VulnStack靶场(三)
  17. Windows下的定时任务设置
  18. Android 五星好评简单实现
  19. 如何使用计算机的加减乘除,计算机是怎么懂加减乘除的
  20. 如何在网页点击按钮显示的图片

热门文章

  1. 开发笔记4——钱包、账户、keyeos、nodeos、cleos概念介绍
  2. 团队作业8--展示博客
  3. 最高效的学习法:一遍学习法
  4. 前端基础知识备忘——parseInt
  5. 【图的连通性】poj2942圆桌骑士
  6. 学生信息管理系统-错误总结
  7. 从四大造字法看文字所承载的文化_高三语文文学常识复习题
  8. 【PSS】PSS学习总结目录
  9. TCP保活机制(KeepAlive)
  10. 【高胜寒碎碎念】2020年度6月复盘