今天上午看了有关单调队列的课件,明天一起整理。
下午做了练习赛,在这儿写一下AC的三道题。
B题,很水的一道题,求数字金字塔中经过数字的最大和。
AC代码及注解如下:
#include<iostream>
using namespace std;
int a[351][351];
int main()
{
int N;
cin>>N;
for(int i=1;i<=N;i++)
{
for(int j=1;j<=i;j++)
cin>>a[i][j];
}
for(int i=N-1;i>=1;i--)//倒序上去
{
for(int j=1;j<=i;j++)
{
if(a[i+1][j]>=a[i+1][j+1])//判断相邻两个数哪个大
a[i][j]+=a[i+1][j];
else a[i][j]+=a[i+1][j+1];
}
}
cout<<a[1][1]<<endl;
}
D题是求N个数中最大素因子所在的那个数。
代码如下:
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int a[20001]={0};
int main()
{
a[1]=1;
for(int i=2;i<20001;i++)//找出所有素数
{
if(a[i]==0)
{
for(int k=i;k<20001;k+=i)
a[k]=i;
}
}
int N;
int t;
while(cin>>N&&N!=-1)//WA两次才知道这个题要求多组输入
{
int m=0;
while(N--)
{
cin>>t;
if(a[t]>a[m]) {m=t;}
}
cout<<m<<endl;
}
}
E题和之前做的棋盘走马的题类似,有一个5*5的棋盘,每个格子上有一个数,从一个格子出发,走五步(每步只能到达相邻的格子),形成一个六位数(可以有前导0),问一共可以形成多少种不同的六位数。
这个题最开始是套路的之前那个题,结果发现自己不知道怎样判断所有六位数是否相同,试了几种方法都没能表达出来,搜了题解发现有使用set去重复的,用上之后就AC了。
代码及注解如下:
#include <iostream>
#include <cstdio>
#include <string>
#include <set>
#include <vector>
using namespace std;
char map[6][6],path[10];
int u[4]={-1,1,0,0},
v[4]={0,0,-1,1};//四个方向
set <string> cnt;//set去重复
string tmp;
void dfs(int x,int y,int step)
{
int tx,ty;
path[step]=map[x][y];
if(step==5)//如果5步走完了储存该6位数
{
tmp.clear();//先清空
for(int i=0;i<=5;i++)
{tmp+=path[i];}//储存6位数到tmp
cnt.insert(tmp);//无重复的放入cnt
return;
}
for(int i=0;i<4;i++)
{
tx=x+u[i];//四个方向
ty=y+v[i];
if(tx>=1&&tx<=5&&ty>=1&&ty<=5)//判断有没有走出棋盘
dfs(tx,ty,step+1);
}
}
int main()
{
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
cin>>map[i][j];
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
dfs(i,j,0);
cout<<cnt.size()<<endl;//cnt是无重复的
return 0;
}
另外三道题有了思路但还没来得及写,晚上再看一下吧。
以上~