目录
算法学习
1.新二叉树
P1305 新二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
https://www.luogu.com.cn/problem/P1305
1.dfs递归:前序:根左右
2.输入问题:题干:特别地,数据保证第一行读入的节点必为根节点。所以,根结点begin单独输入,后续节点for中 i=1从1开始输入;
3.注意:getchar();洛谷c编译器对struct的读入bug;
#include<stdio.h>
struct node
{
char l,r;
} tree[100];
void dfs(char ch) //前序遍历
{
printf("%c",ch); //根
if(tree[ch].l!='*')dfs(tree[ch].l); //左
if(tree[ch].r!='*')dfs(tree[ch].r); //右
}
int main()
{
int n;
char a,l,r,begin;
scanf("%d",&n);
getchar(); //注意吸收回车
scanf(" %c%c%c",&begin,&l,&r); //洛谷c编译器问题,加个空格‘ ’对应结构体
getchar();
tree[begin].l=l;
tree[begin].r=r;
for(int i=1; i<n; i++)
{
scanf(" %c%c%c",&a,&l,&r);
tree[a].l=l;
tree[a].r=r;
getchar();
}
dfs(begin);
return 0;
}
2.二叉树深度(高度)P4913 【深基16.例3】二叉树深度 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
https://www.luogu.com.cn/problem/P4913
1.结构体设置:孩子表示法,读入left,right(左右孩子)
2.搜索dfs(不撞南墙不回头):参量设置pos,deep,分别为该结点pos,树的深度deep
3.终止条件:找到叶子(0,0),叶子无孩子不再向下延伸,同时找深度max
#include<stdio.h>
struct node
{
int l;
int r;
}tree[1000005];
int ans=-1; //比较深度,初始值设小点
int max(int a,int b)
{
return a>b?a:b;
}
void dfs(int pos,int deep)
{
if(tree[pos].l==0&&tree[pos].r==0) //==叶节点时,结束深搜
{
ans=max(ans,deep); //每层到达叶节点深度不同,找max
return ;
}
dfs(tree[pos].l,deep+1); //递归,搜索下一层left
dfs(tree[pos].r,deep+1); //递归,搜索下一层right
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&tree[i].l,&tree[i].r);
}
dfs(1,1); //第一层开始搜
printf("%d",ans);
}
刷题网站
1.全排列
问题 L: 全排列(JSU-ZJJ)(❤❤❤❤) - OJ (jsuacm.cn)
http://jsuacm.cn/problem.php?cid=1687&pid=11
1.思路: 可以用swap模拟搜索过程;
2.for循环设置:与同一字符数组里的其他字符交换
3.注意:利用字符输入字符数组时,空格也被当作字符输入,需要特判if(c!=' ') s[m++]=c
#include<stdio.h>
char s[6];
int n;
void dfs(int step)
{
int i;
if(step==n-1)
{
for(i=0;i<n;i++)
{
printf("%c",s[i]);
}
printf("\n");
return ;
}
else
{
for(i=step;i<n;i++)
{
char x; //注意中间变量类型
x=s[step];
s[step]=s[i];
s[i]=x; //交换
dfs(step+1);
x=s[step]; //回溯还原
s[step]=s[i];
s[i]=x;
}
}
}
int main()
{
int k;
while(~scanf("%d",&k)) //多组输入
for(int i=0;i<k;i++)
{
scanf("%d\n",&n);
int m=0;
for(int i=0;i<=n*2-1;i++)
{
char c;
c=getchar();
if(c!=' ')
s[m++]=c;
}
s[m]='\0';
dfs(0);
printf("\n");
}
}
2.找规律
问题 G: 奇怪的棋盘 - OJ (jsuacm.cn)
http://jsuacm.cn/problem.php?cid=1687&pid=6 1.关键:找规律,通项公式
此类题注意数据类型
#include<stdio.h>
int main()
{
long long int a[55],i;
a[1]=1;a[2]=2;
for(i=3;i<51;i++)
a[i]=a[i-1]+a[i-2];
int n;
while(~scanf("%d",&n))
{
printf("%lld\n",a[n]);
}
}
3.萝卜的冒泡排序
问题 C: 萝卜的冒泡排序 - OJ (jsuacm.cn)
http://jsuacm.cn/problem.php?cid=1686&pid=2
1.关键点:冒泡排序只能统计不同元素的交换个数,相同元素交换个数找规律;
2.注意:112223,每找到一次相同元素时就加上相应个数,不要把全部相同个数找完,1相同个数为2,2相同个数为3;
#include<stdio.h>
int main()
{
int n,i,j,a[150];
int ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++)
{
if(a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
ans++;
}
}
int k=1;
for(int i=0; i<n-1; i++)
{
if(a[i]==a[i+1])
{
k++; //相邻元素相同,一
ans+=k-1; //加上相同元素之间交换的次数
}
else
k=1; //相邻元素不同,重新计数
}
printf("%d\n",ans);
}