A-平方序列
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小明想找到两个正整数 X 和 Y ,满足
1、2019
请你求出在所有可能的解中,X+Y的最小值是多少?
组成等差数列。
请你求出在所有可能的解中,X +Y 的最小值是多少?
运行限制
最大运行时间:1s
最大运行内存: 128M
思路:
根据等差数列的性质得出XY之间的关系 如代码
#include
using namespace std;
int main(){
for(int i=2020;;i++){
int yy=2*i*i-2019*2019;//根据等差数列得出
int y=sqrt(yy);
if(y*y==yy){
cout<<i+y<<endl;
return 0;//7020
}
}
return 0;
}
B-质数拆分
将2019拆分为若干个两两不同的质数之和,一共有多少种不同的方法?注意交换顺序视为同一种方法,例如2 + 2017 = 2019与2017 + 2 = 2019视为同一种方法。
思路:
把1~2019所有的素数都保存下来在一个数组里,只需要最后组成的合为2019即可,就变成从素数里选 然后组成2019,和背包问题相似
#include
using namespace std;
int zhishu[2000];
int step=0;//存质数的下标
long long save[3000][3000];//记忆化搜索 缩短时间 不然会超时算不出
void get(){
for(int i=2;i<2019;i++){
int flag=1;
for(int j=2;j*j<=i;j++){
if(i%j==0){
flag=0;
break;
}
}
if(flag){
zhishu[step++]=i;
}
}
}
long long find(int pos,long long sum){
if(sum==2019){
return 1;
}
if(pos>=step||sum>2019){
return 0;
}
if(save[pos][sum]!=0){
return save[pos][sum];
}
long long ans1=0;
ans1+=find(pos+1,sum);
ans1+=find(pos+1,sum+zhishu[pos]);
save[pos][sum]=ans1;
return ans1;
}
int main(){
get();
cout<<find(0,0)<<endl; //答案55965365465060
return 0;
}
C-拼接
D-求值
学习了约数后,小明对于约数很好奇,他发现,给定一个正整数t,总是可以找到含有t个约数的整数。小明对于含有t个约数的最小数非常感兴趣,并把它定义为St。例如S1= 1,S2= 2,S3= 4,S4= 6,。现在小明想知道,当t= 100时,St是多少?即S100是多少?
思路:
这题的思路感觉就是暴力搜,找出满100个约数的数。
#include
using namespace std;
int main(){
int sum=100;
for(int i=2;;i++){
int ans=0;
for(int j=2;j<i;j++){
if(i%j==0){
ans++;
}
}
if(ans+2==sum){ //+2是因为还有一和他自身
cout<<i<<endl; //45360
return 0;
}
}
return 0;
}
这里有个求一个数有多少约数的代码 有兴趣可以看看
有一个公式就是说
6=21 * 31 所以6的约数数目为 (1+1)(1+1)=4
8=23 所以8的约数数目为(3+1)=4
#include
using namespace std;
int size[50000];
int main(){
int num=45360; //可以随便更换 要是太大的话记得开longlong
for(int i=2;i*i<=num;i++){
while(num%i==0){
size[i]++;
num/=i;
}
}
if(num!=1){
size[num]++;
}
int ans=1;
for(int i=2;i<=45360;i++){
if(size[i]){
ans*=(size[i]+1);
}
}
cout<<ans<<endl; //得出是100正确
return 0;
}
E-路径计数
有一个7X7的方格。方格左上角顶点坐标为(0,0),右下角坐标为(7,7)。
求满足下列条件的路径条数:
1、起点和终点都是(0,0)
2、路径不自交
3、路径长度不大于12
4、对于每一个顶点,有上下左右四个方向可以走,但是不能越界。
思路
其实6X6和7X… 更大的方格都是一样的 最大12步会有限制最远到达的地方
在6X6时候就已经到了最大
#include
using namespace std;
int vis[9][9];
int ans=0;
int xx[4]={0,0,-1,1};
int yy[4]={1,-1,0,0};
bool val(int x,int y,int step){
if(x<0||x>6||y<0||y>6){
return false;
}
if(vis[x][y]==1) return false;
if(step>12){
return false;
}
return true;
}
void dfs(int x,int y,int step){
if(x==0&&y==0&&step!=2&&step!=0){
ans++;
return;
}
for(int i=0;i<4;i++){
int x1=x+xx[i];
int y1=y+yy[i];
if(val(x1,y1,step+1)){
vis[x1][y1]=1;
dfs(x1,y1,step+1);
vis[x1][y1]=0;
}
}
}
int main(){
dfs(0,0,0);
cout<<ans<<endl; //206
return 0;
}
F-最优包含
题目给定两个字符串S和T,保证S的长度不小于T的长度,问至少修改S的多少个字符,可以令T成为S的子序列。
输入描述:
两行。
第一行是字符串S,第二行是字符串T。
保证S的长度不小于T的长度,S的长度范围在10~1000之间。
输出描述:
答案,一个非负整数。
输入样例:
XBBBBBAC
ACC
输出样例:
2
思路
用dp[i][j] i 代表第一行字符串下标 j代表第二行字符串下标
dp[i][j]表示用i个字符最优包含j个字符的最小修改数
当第一行第i个 等于第二行第j个时结果不变即dp[i][j]=dp[i-1][j-1];
当不相等时 dp[i][j]=min(dp[i-1][j],dp[i-1][j-1]+1)
#include
using namespace std;
int dp[1005][1005];
int main(){
string s1,s2,str1,str2;
cin>>str1>>str2;
s1="a"+str1;
s2="b"+str2;
memset(dp,0x3f3f3f3f,sizeof dp);
dp[0][0]=0;
for(int j=1;j<s2.size();j++){
for(int i=j;i<s1.size();i++){
if(s1[i]==s2[j]){
dp[i][j]=dp[i-1][j-1];
}else{
dp[i][j]=min(dp[i-1][j-1]+1,dp[i-1][j]);
}
}
}
cout<<dp[s1.size()-1][s2.size()-1]<<endl;
return 0;
}
G-排列数
对于一个数列中的某个数,如果这个数比两侧的数都大或比两侧的数都小,我们称这个数为这个数列的一个转折点。
如果一个数列有t个转折点,我们称这个数列为t+1调数列。
给定两个正整数n,k。求在1~n的全排列中,有多少个数列是k调数列。
输入描述:
两个正整数n,k。
输出描述:
答案,一个整数。
输入样例:
4 2
1
输出样例:
12
思路
对n个数进行全排 如果满足k 答案+1 最后输出答案
#include
using namespace std;
typedef long long ll;
ll ans1=0;
int n,k;
int vis[1005];
ll get(vector<int>ans){
if(ans.size()<n){
return 0;
}
int k=1;
for(int i=1;i<ans.size()-1;i++){
if(ans[i]>ans[i-1]&&ans[i]>ans[i+1]){
k++;
}else if(ans[i]<ans[i-1]&&ans[i]<ans[i+1]){
k++;
}
}
return k;
}
void find(vector<int>ans){
if(ans.size()==n){
if(get(ans)==k)
ans1++;
return;
}
for(int i=1;i<=n;i++){
if(vis[i]!=1){
ans.push_back(i);
vis[i]=1;
find(ans);
ans.pop_back();
vis[i]=0;
}
}
}
int main(){
cin>>n>>k;
vector<int>ans;
find(ans);
cout<<ans1%123456<<endl;
return 0;
}
H-解谜游戏
小明正在玩一款解谜游戏。谜题由24根塑料棒组成,其中黄色塑料棒4根,红色8根,绿色12根(后面用Y表示黄色、R表示红色、G表示绿色)。初始时这些塑料棒排成三圈,如上图所示,外圈12根,中圈8根,内圈4根。小明可以进行三种操作:
1.将三圈塑料棒都顺时针旋转一个单位。例如当前外圈从0点位置开始顺时针依次是YRYGRYGRGGGG,中圈是RGRGGRRY,内圈是GGGR。那么顺时针旋转一次之后,外圈、中圈、内圈依次变为:GYRYGRYGRGGG、YRGRGGRR和RGGG。
2.将三圈塑料棒都逆时针旋转一个单位。例如当前外圈从0点位置开始顺时针依次是YRYGRYGRGGGG,中圈是RGRGGRRY,内圈是GGGR。那么逆时针旋转一次之后,外圈、中圈、内圈依次变为:RYGRYGRGGGGY、GRGGRRYR和GGRG
3.将三圈0点位置的塑料棒做一个轮换。具体来说:外圈0点塑料棒移动到内圈0点,内圈0点移动到中圈0点,中圈0点移动到外圈0点。例如当前外圈从0点位置开始顺时针依次是YRYGRYGRGGGG,中圈是RGRGGRRY,内圈是GGGR。那么轮换一次之后,外圈、中圈、内圈依次变为:RRYGRYGRGGGG、GGRGGRRY和YGGR。小明的目标是把所有绿色移动到外圈、所有红色移动中圈、所有黄色移动到内圈。给定初始状态,请你判断小明是否可以达成目标。
输入描述: 输出描述: 思路 I-第八大奇迹
第一行包含一个整数T,代表询问的组数。(1
对于每组询问,输出一行YES或者NO,代表小明是否可以达成目标。
2
GYGGGGGGGGGG
RGRRRRRR
YRYY
YGGGRRRRGGGY
YGGGRRRR
YGGG
1
2
3
4
5
6
7
输出样例:
YES
NO
其实有个规律就是以四个字符为一组
外圈1 2 3 4 1 2 3 4 1 2 3 4
中圈1 2 3 4 1 2 3 4
内圈1 2 3 4
它们的1234下标分别对齐 通过旋转可以变换对齐
所以可以分为4组
每组的G=3 R=3 Y=1才能解密成功 根据这一条件#include
J-燃烧权杖