第一场第一题:
#include<bits/stdc++.h>
#define MAX 150005
#define MOD 1000000007
typedef long long LL;
//const int INF = 1e9+7;
#define VM 1000010
using namespace std;
#define inf 0.00000001
//2019年第一场的第一题,给定区间[a,b],输出这个区间里最长的连续合数段
int a[1000005];
int count1 = 0;
int maxn = 1, tag = 0;
//判断合数
bool judge(int n)
{
for (int i = 2; i <= (int)sqrt(n); i++)
if (n%i == 0)
if (n != 2)
return true;
return false;
}
//把合数存到数组a
void save(int n, int m)
{
for (int i = n; i <=m; i++)
if (judge(i))
{
a[count1] = i;
count1++;
}
}
void compare(int a[])
{
int m = 1;
for (int i = 0; i < count1; i++)
if (a[i + 1] - a[i] == 1)
m++;
else
{
if (m > maxn)
{
maxn = m;
tag = i;//连续合数的最后一个
}
m = 1;
}
}
//主函数
int main()
{
int n, m;
scanf("%d %d", &n, &m);
save(n, m);
compare(a);
for (int i = tag - maxn+1; i <= tag; i++)
{
printf("%d ", a[i]);
}
return 0;
}
第二场第一题:
区间素数等差数列
#include<bits/stdc++.h>
#define MAX 150005
#define MOD 1000000007
typedef long long LL;
//const int INF = 1e9+7;
#define VM 1000010
using namespace std;
#define inf 0.00000001
int sushu(int n){
for(int i = 2;i*i<=n;i++){
if(n%i==0){
return 0;
break;
}
}
return 1;
}
int main()
{
int a,b,arr[100000];
int n;
//scanf("%d",&n);
//if(sushu(n)==1)printf("1\n");
scanf("%d%d",&a,&b);
int k = 0;
for(int i = a;i<b+1;i++){
if(sushu(i)==1){
arr[k] = i;
//printf("%d ",arr[k]);
k++;
}
}
//printf("\n\n");
int count=1,temp=arr[1]-arr[0];
int ii;
for(int j=0;j<k;j++){
ii=j;
while(arr[ii]+temp == arr[ii+1]){
count++;
ii++;
}
if(count>2){
for(int m=0;m<count;m++){
printf("%d ",arr[ii-count+m+1]);
}
printf("\n");
count=1;
}
temp=arr[j+1]-arr[j];
}
return 0;
}
第一场第二题:给出几种网络设备(主机、交换机、路由器等),交换机最多八个接口,组成树形网络拓扑,要求给一台主机的编号,求距离它最近的交换机的编号(或者可能是输出路径),如果有多台最近交换机,则输出先序遍历最前边的那个。
这个题没数据,自己设计了一个。思路就是建八叉树,再相应建一个无向图,先把交换机节点按先序顺序先后存一下,然后给一个出发点,以每个交换机节点为出发点bfs无向图求到出发点的最短路(边权视为1,这里懒得用什么高端最短路算法了),顺便存了下路径(第二场第二题其实也可以bfs,思路差不多)。找一个最小的最短路就行。
#include<bits/stdc++.h>
#define MAX 150005
#define MOD 1000000007
typedef long long LL;
//const int INF = 1e9+7;
#define VM 1000010
using namespace std;
#define inf 10000007
/*
struct node{
char c;
int num;
bool operator < (const node &a)const
{
if(num!=a.num)
return num < a.num;
return c>a.c;
}
}nd[1005];
template<typename T> string toString(const T& t){
ostringstream oss; //创建一个格式化输出流
oss<<t; //把值传递如流中
return oss.str();
}
struct node{
int id;
int zl;//设备的类别
int fz;//分支数
};*/
int que[1005];
int nd[1005][8];
vector<int> dian;
void qxbl(int root){
if(root!=-1){
//cout<<root<<" ";
if(que[root]==3)
dian.push_back(root);//交换机按先序遍历顺序存储编号
qxbl(nd[root][0]);
qxbl(nd[root][1]);
qxbl(nd[root][2]);
qxbl(nd[root][3]);
qxbl(nd[root][4]);
qxbl(nd[root][5]);
qxbl(nd[root][6]);
qxbl(nd[root][7]);
}
}
//设备类别:1主机 2路由器 3交换机
vector<int> g[1005];//建无向图
int dis[1005];
int path[1005];//存储路径用,需要输出路径就反响找一下即可
int bfs(int st,int ed){
queue<int> qu;
int i;
for(i=0;i<1005;i++)dis[i]=inf;
dis[st]=0;
qu.push(st);
while(!qu.empty()){
int v=qu.front();
qu.pop();
for(i=0;i<g[v].size();i++){
if(dis[g[v][i]]==inf){
dis[g[v][i]]=dis[v]+1;
path[g[v][i]]=v;
if(g[v][i]==ed)return dis[g[v][i]];
qu.push(g[v][i]);
}
}
}
return inf;
}
int main()
{
int m,q,i,j,k;
int a[8];
int root;
int idx,id,zl;
scanf("%d",&m);//
for(i=0;i<m;i++){
scanf("%d%d",&idx,&zl);
//scanf("%d%d",&que[i].id,&que[i].zl);
//scanf("%d",&que[i].fz);
que[idx]=zl;
if(i==0)root=idx;
for(j=0;j<8;j++){//输入结点的分支和该分支的种类,-1表示空
scanf("%d",&id);
if(id!=-1){
scanf("%d",&zl);
que[id]=zl;
g[idx].push_back(id);
g[id].push_back(idx);
}
nd[idx][j]=id;
for(k=0;k<8;k++)nd[id][k]=-1;//默认输入的子节点都是叶子
}
}
qxbl(root);
//cout<<endl;
int len=0,aim,ans,minn=MAX;
scanf("%d",&aim);//出发点
for(i=0;i<dian.size();i++){
//cout<<dian[i]<<" ";
//cout<<endl;
len = bfs(dian[i],aim);
if(len<minn){//严格小于才更新
minn=len;
ans=i;
}
}
printf("%d %d\n",dian[ans],minn);
return 0;
}
5
1 1
2 1 3 1 4 2 -1 -1 -1 -1 -1
2 2
5 1 6 3 7 1 8 1 -1 9 1 10 1 -1
4 2
11 1 12 1 -1 -1 -1 -1 -1 -1
6 3
-1 13 1 -1 14 1 15 1 -1 -1 -1
11 1
16 1 -1 -1 -1 -1 -1 -1 -1
第二场第二题:
题目描述:(看的网上学弟的题目描述,很全)一个关于三叉树的题目,小于100的值代表树叶,大于100的值为分支点,建树的过程是水平方向建树,输入格式:
先输入n,代表有n组数据,接下来n行,输入4个数,第一个数代表根节点,接下来分别代表三个子节点,-1代表子节点不存在,输入的顺序按照层次遍历的次序。接下来,要求寻找叶子节点的最短路径,最短路径是指不经过重复的边。输入方式,首先输入一个值m,代表m行,接下来m行输入m个叶子节点和对应的优先级,要求按优先级输出从上次到达的位置到该节点的最短路径,每条路径的最后一个节点要求输出目标叶子节点,最后要求回到根节点。
---------------------
作者:sinat_38425013
来源:CSDN
原文:https://blog.csdn.net/sinat_38425013/article/details/88749325
样例:
10
100 101 108 107
101 1 102 2
108 103 104 105
107 17 109 18
102 3 4 5
103 7 8 9
104 10 106 11
105 15 16 -1
109 19 20 21
106 12 13 14
5
8 1
14 3
16 2
5 0
19 4
answer:
100 101 102 5
102 101 100 108 103 8
103 108 105 16
105 108 104 106 14
106 104 108 100 107 109 19
109 107 100
和18年第二题树形态很类似,17年LCA改改其实也可以A这个,主要是换成三叉再加个合并路径。
不过显然bfs写这个题代码量更少(基本和上边那个题一样的写法),不过复杂度就不好说了。。。反正都是小数据量。。
#include<bits/stdc++.h>
#define MAX 150005
#define MOD 1000000007
typedef long long LL;
//const int INF = 1e9+7;
#define VM 1000010
using namespace std;
#define inf 0.00000001
/*
struct node{
char c;
int num;
bool operator < (const node &a)const
{
if(num!=a.num)
return num < a.num;
return c>a.c;
}
}nd[1005];
template<typename T> string toString(const T& t){
ostringstream oss; //创建一个格式化输出流
oss<<t; //把值传递如流中
return oss.str();
}*/
struct node{
int id;
int pri;
}que[1005];
bool cmp(node a,node b){
return a.pri<b.pri;
}
int nd[1005][3];
vector<int> path1,path2;
//int len1,len2;
void getpath(int d,int root,vector<int> &path){//求根到目标节点的路径(不包含根)
if(d==root)return ;//根自己
if(root>=100){
//printf("%d\n",root);
for(int i=0;i<3;i++){
if(nd[root][i]==d){
path.push_back(d);//判断是否找到目标节点,若找到直接返回
return ;
}
if(nd[root][i]>=100){
path.push_back(nd[root][i]);
getpath(d,nd[root][i],path);
}
else continue;
int len=path.size();
if(!path.empty()&&!(d==path[path.size()-1]))//防止找到目标节点后仍然有其他节点加入路径
path.erase(path.begin()+len-1,path.begin()+len);
}
}
}
void printshortpath(int root){
vector<int> anspath;
int times=0; //记录path1元素的访问次数
int i,j;
for(i=0;i<path1.size();i++){
vector<int>::iterator it;
it = find(path2.begin(),path2.end(),path1[i]);
if(it!=path2.end()){ //判断path2里含path1的某个节点,即一个LCA
for(j=path2.size()-1;j>i;j--) //合并路径
anspath.push_back(path2[j]);
for(j=i;j<path1.size();j++)
anspath.push_back(path1[j]);
break;
}
else{
times++;
if(times==path1.size()){//path1和path2没有公共元素,LCA是根节点
for(i=path2.size()-1;i>=0;i--)//合并路径
anspath.push_back(path2[i]);
anspath.push_back(root);
for(i=0;i<path1.size();i++){
anspath.push_back(path1[i]);
}
}
}
}
for(i=1;i<anspath.size();i++)//输出路径
cout<<anspath[i]<<" ";
cout<<endl;
}
void qxbl(int root){
if(root!=-1){
cout<<root<<" ";
qxbl(nd[root][0]);
qxbl(nd[root][1]);
qxbl(nd[root][2]);
}
}
int main()
{
int m,q,i,j;
int a,b,c,d;
int root;
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
if(i==0)root=a;
nd[a][0]=b;
nd[a][1]=c;
nd[a][2]=d;
if(b<100){
nd[b][0]=nd[b][1]=nd[b][2]=-1;
}
if(c<100){
nd[c][0]=nd[c][1]=nd[c][2]=-1;
}
if(d<100){
nd[d][0]=nd[d][1]=nd[d][2]=-1;
}
}
//qxbl(root);
//cout<<endl;
scanf("%d",&q);
for(i=0;i<q;i++){
scanf("%d%d",&que[i].id,&que[i].pri);
}
sort(que,que+q,cmp);
//for(i=0;i<q;i++)cout<<que[i].id<<" ";
//cout<<endl;
printf("%d ",root);
for(i=0;i<q;i++){
//memset(path1,0,sizeof(path1));
//memset(path2,0,sizeof(path2));
path1.clear();
path2.clear();
//len1=len2=0;
if(i==0){
//getpath(root,root,path1);
getpath(que[0].id,root,path2);
for(j=0;j<path2.size()-1;j++)
cout<<path2[j]<<" ";
cout<<path2[j];
}
else{
getpath(que[i-1].id,root,path2);
getpath(que[i].id,root,path1);
}
/*for(j=0;j<path1.size();j++)
cout<<path1[j]<<" ";
cout<<endl;
for(j=0;j<path2.size();j++)
cout<<path2[j]<<" ";
cout<<endl;*/
printshortpath(root);
}
path2.clear();
getpath(que[q-1].id,root,path2);
for(j=path2.size()-2;j>=1;j--)
cout<<path2[j]<<" ";
cout<<path2[0]<<" "<<root<<endl;
return 0;
}