在软协的一周

和算法斗智斗勇

在经历了一周的算法大战后,总算摸到了算法的尾巴(虽然算法好像没有尾巴)接下来就总结一下我的收获:

1.对排序的回顾

对于排序算法的理解:
1.桶排序:需要一个数组三个变量,注意数组的大小为你要存元素的最大值
基本思想:将想要排序的数存放在数组里,初始化数组使每一个元素为0,然后用循环依次读入每一个数,然后数组中存放的为这个数字出现的次数,然后最后,将这个数组按照次数依次输出即可。
特别注意的点:
1.数组的初始化
2.在进行二次循环的话,要记得判断次数最少为1,次数为0的不输出。

#include<stdio.h>
int main()
{
	int a[100]={0},i,j,t;//一个数组,三个变量 ,且完成初始化(for循环也可,但简化代码) 
	for(i=0;i<5;i++)//如果比较个数未知,那么就在设置一个变量n
	{
		scanf("%d",&t);//读入数据,并且数组中存的为次数 
		a[t]++;
	}
	for(i=0;i<=100;i++)//从小到大,如果从大到小,将数组反向遍历输出即可 
	{
		for(j=1;j<=a[i];j++)//按照次数输出下标,但是要注意下标要大于等于1,不能为0 
		{
			printf("%d",i);
		}
	}
	return 0;
	
 } 

2.冒泡排序:需要一个数组,三个变量
基本原理:比较相邻的元素,假如第一个比第二个大,那么交换(从小到大),反之则是从大到小排。
需要注意的点:一共要比n-1躺,要注意数组越界问题
还有一点就是上下是配套的,假如数组从下标为1开始,那么所有下标都要为1,并且带等号,且二层循环不减一;
如果从0开始,那么都要从零开始,并且不带等号,二层循环减一(先记住,再理解)

#include<stdio.h>
int main()
{
	int a[10],i,j,t,n;
	scanf("%d",&n);//输入你想要比较的数字个数 
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);//读入各个数字 
	}
	for(i=0;i<n-1;i++)//比较n-1趟 
	{
		for(j=0;j<n-i-1;i++)//当前这一位要比较多少趟 
		{
			if(a[j]<a[j+1])//右小左大 
			{
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		printf("%d",a[i]);//遍历输出 
	}
	return 0;
	
 } 

3.快速排序:需要一个数组和未知数n,还有left,right,两个指针型的东西,四个变量

#include<stdio.h>
int a[101],n;
void quicksort(int left,int right)
{
	int i,j,t,temp;
	if(left>right)
	return;
	temp=a[left];
	i=left;
	j=right;
	while(i!=j)
	{
		while(a[j]>=temp&&i<j)
		{
			j--;
		}
		while(a[i]<=temp&&i<j)
		{
			i++;
		}
	}
	if(i<j)
	{
		t=a[i];
		a[i]=a[j];
		a[j]=t;
	}
	a[left]=a[i];
	a[i]=temp;
	quicksort(left,i-1);
	quicksort(j+1,right);
	return;
}

重点是学会快速排序的调用!

2.序列的延伸(栈,队列,链表)

队列:队列是一种特殊的线性结构,它只允许在队列的首部进行删除操作,这称为出队,而在队列的尾部进行插入操作,这称为入队(首删尾入)
重点掌握:出队入队操作

#include<stdio.h>
int main()
{
	int a[102]={0,6,3,1,7,5,8,9,2,4},head,tail;
	head=1;
	tail=10;
	while(head<tail)
	{
		printf("%d",a[head]);//打印队首并出队,如果出队,直接指向首元素的那个类似于指针的东西++; 
		head++;
		a[tail]=a[head];
		tail++;//增添相同道理,只不过指向队尾的类似于指针的东西(也能理解为数组的下标)++ 
		head++
	}
	return 0;
	
}

栈:
1.和队列的区别:
队列(Queue):是限定只能在表的一端进行插入和另一端删除操作的线性表
栈(Stack):是限定之能在表的一端进行插入和删除操作的线性表
队列:先进先出
栈:先进后出
用栈来判断回文数:

#include<stdio.h>
#include<string.h>
int main()
{
	char a[101],s[101];
	int i,len,mid,next,top;
	gets(a);
	len=strlen(a);
	mid=len/2-1;
	top=0;
	for(i=0;i<mid;i++)
	{
		s[++top]=a[i];
	}
	if(len%2==0)
	{
		next=mid+1;
	}
	else
	    next=mid+2;
	for(i=next;i<=len-1;i++)
	{
		if(a[i]!=s[top])
		break;
		top--;
	}
	if(top==0)
	{
		printf("YES");
	}
	else 
	printf("NO"); 
 } 
 

至少先记住,然后再理解不迟
链表:以前做过概述,不作详细解释
洛谷好题详解:
小南有一套可爱的玩具小人, 它们各有不同的职业。

有一天, 这些玩具小人把小南的眼镜藏了起来。 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图:

这时singersinger告诉小南一个谜題: “眼镜藏在我左数第3个玩具小人的右数第11个玩具小人的左数第22个玩具小人那里。 ”

小南发现, 这个谜题中玩具小人的朝向非常关键, 因为朝内和朝外的玩具小人的左右方向是相反的: 面朝圈内的玩具小人, 它的左边是顺时针方向, 右边是逆时针方向; 而面向圈外的玩具小人, 它的左边是逆时针方向, 右边是顺时针方向。

小南一边艰难地辨认着玩具小人, 一边数着:

singersinger朝内, 左数第33个是archerarcher。

archerarcher朝外,右数第11个是thinkerthinker。

thinkerthinker朝外, 左数第22个是writewriter。

所以眼镜藏在writerwriter这里!

虽然成功找回了眼镜, 但小南并没有放心。 如果下次有更多的玩具小人藏他的眼镜, 或是谜題的长度更长, 他可能就无法找到眼镜了 。 所以小南希望你写程序帮他解决类似的谜題。 这样的谜題具体可以描述为:

有 nn个玩具小人围成一圈, 已知它们的职业和朝向。现在第11个玩具小人告诉小南一个包含mm条指令的谜題, 其中第 zz条指令形如“左数/右数第ss,个玩具小人”。 你需要输出依次数完这些指令后,到达的玩具小人的职业。
开始解答
对于题目分析:首先小人有两个坐向,其次对于东西传的方向,也有区别,所以大致思路是,将其分为四类正向向左,反向向右,正向向右,反向向左,这样可以分为逆时针还是顺时针转动,从而达到目的,鉴于,有位置和名字两个变量,需用到结构体,具体代码如下:

#include<stdio.h>
struct {                
	int id; //记录坐向             
	char name[15];//记录名字         
}stu[100000];
 
int next[][2] = { -1, 1, 1, -1 };//四种搭配,两种为逆时针正,两种为顺时针逆       
 
int main() { 
	int n, m, i, ans, dir, num;           
	ans =  0;              
	scanf("%d %d", &n, &m);//n代表几个小人
	for (i = 0; i < n; i++)
		scanf("%d %s", &stu[i].id, stu[i].name);  
	for (i = 0; i < m; i++) {//m代表方向和步数
		scanf("%d %d", &dir, &num);        
		ans += num * next[stu[ans].id][dir];  
		if (ans < 0)   
			ans = n - ((-1) * ans) % n;  //将顺时针转的转化为逆时针转的
		else if (ans >= n)   
			ans %= n; //如果大于一圈,那就取余
	}
	printf("%s", stu[ans].name);         
 
 
	return 0;
}

纯纯模拟题目,按照题目要求来就行。
以前做过的洛谷题复盘(p5717)
题目:给出三条线段 a,b,ca,b,c 的长度,均是不大于 10000 的整数。打算把这三条线段拼成一个三角形,它可以是什么三角形呢?

如果三条线段不能组成一个三角形,输出Not triangle;
如果是直角三角形,输出Right triangle;
如果是锐角三角形,输出Acute triangle;
如果是钝角三角形,输出Obtuse triangle;
如果是等腰三角形,输出Isosceles triangle;
如果是等边三角形,输出Equilateral triangle。
如果这个三角形符合以上多个条件,请按以上顺序分别输出,并用换行符隔开。
做题心得:
这道题不是很难,但是对于初学者来说很容易判断错条件和跳出循环的条件,最后不能ac

#include<stdio.h>
int main()
{
	int a,b,c,tmp;//手动排序,C语言
	scanf("%d%d%d",&a,&b,&c);
	if(a>b){
		tmp=a;
		a=b;
		b=tmp;
	}
	if(a>c){
		tmp=a;
		a=c;
		c=tmp;
	}
	if(b>c){
		tmp=b;
		b=c;
		c=tmp;
	}//a<b<c
	if(a+b>c){
		if(a*a+b*b==c*c)//直角 
		printf("Right triangle\n");
		if(a*a+b*b>c*c)//锐角 
		printf("Acute triangle\n");
		if(a*a+b*b<c*c)//钝角
		printf("Obtuse triangle\n"); 
		if(a==b||a==c||b==c)//等腰 
		printf("Isosceles triangle\n");
		if(a==b&&b==c)//等边三角形 
		printf("Equilateral triangle\n");
	}
	else printf("Not triangle\n");
	
	return 0;

}


做题要点:就是要把三边大小判断好,并且以后再写题的时候注意条件结构嵌套的时候;有没有可能出现,特判隐含在补集中这种情况。

最后就是c语言了

1.宏定义

在这里插入图片描述
宏定义的要点:
1.定义时一定不能有分号;
2.宏定义如果嵌套使用必须按照后定义的那个;
3;宏定义只是简单的替换,不同于typedef
4.宏定义的#和##用法
5.宏定义可以用来写链表

这周就这样吧,下周再见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值