约瑟夫环实验

本文介绍了如何使用C++编程语言和EasyX库实现一个基于用户输入的约瑟夫环动画,通过循环单链表表示圆,随着删除数的增加,圆会按照特定规则消失并重现。
摘要由CSDN通过智能技术生成

分享一个约瑟夫环实验,看效果图吧。

首先获取用户输入

根据用户输入,会自动生成相应的约瑟夫环,循环到相应的删除数时,圆变成黄色,并且先变大再逐渐变小直至消失。

下面是完整代码:

#define _CRT_SECURE_NO_WARNINGS
#include<string>
#include<conio.h>
#include<graphics.h>
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<easyx.h>  
using namespace std;
int m ,n ;
int R = 250, R1 = 330, r = 40;

typedef struct node
{
	int num;
	int x;
	int y;
	int r;
	node* next;
	int color;//默认小圆的颜色为蓝色
}node, * link;

link creat_link(int num) //建立num个元素的循环单链表
{
	link head = NULL;
	node* p, * q;
	if (num <= 0) return head;
	head = new(node);//新建节点
	head->num = 1;
	head->color = BLUE;
	head->x = R;//第一个节点固定在x轴上
	head->y = 0;
	head->r = r;
	head->next = head;//形成循环单链
	q = head;
	for (int i = 1; i <= num; i++)//在循环单链中,利用尾插法插入另外的n-1个节点
	{
		p = new(node);
		p->num = i;
		p->color = BLUE;
		p->x = cos(2 * 3.141592 * (i - 1) / n) * R;//圆心x坐标
		p->y = -1 * sin(2 * 3.141592 * (i - 1) / n) * R;//圆心y坐标
		p->r = r;
		p->next = q->next;
		q->next = p;
		q = p;
	}
	return head;
}
void initWin()
{
	initgraph(800, 800);//初始化界面
	setorigin(400, 400);//设置原点
	setbkcolor(BLACK);//设置背景色
	setfillcolor(BLUE);//设置填充颜色
	settextcolor(YELLOW);//设置字体颜色
	cleardevice();
}
//输出圆的提示文字
void print(int n) {
	node* p1, * q1;
	p1 = (node*)malloc(sizeof(node));
	p1->next = NULL;
	p1->next = p1;
	for (int i = 1; i <= n; i++) {
		q1 = (node*)malloc(sizeof(node));
		q1->num = i;
		q1->x = cos(2 * 3.141592 * (i - 1) / n) * R1;
		q1->y = -1 * sin(2 * 3.141592 * (i - 1) / n) * R1;
		q1->next = p1->next;
		p1->next = q1;
	}
	p1 = p1->next;
	for (int i = 0; i < n; i++) {
		TCHAR a[100];
		_stprintf(a, _T("%d"), p1->num);
		outtextxy(p1->x, p1->y, a);
		p1 = p1->next;
	}
}
void deleteCircle(node* p)//p指针所指向的节点,原地缩小直至消失
{
	//突出显示
	int color = getpixel(p->x, p->y);//获取(x,y)点的颜色值
	color = 0xFFFFFF - color;//取反色
	setfillcolor(color);
	fillcircle(p->x, p->y, p->r);
	Sleep(500);
	color = 0xFFFFFF - color;//取反色
	setfillcolor(color);
	fillcircle(p->x, p->y, p->r);

	//放大圆的过程
	float tempR = p->r;
	color = 0xFFFFFF - color;//取反色
	setfillcolor(color);
	for (int i = 1; i <= 5; i++)
	{
		fillcircle(p->x, p->y, tempR);
		tempR = 1.1 * tempR;
		p->color = BLUE;
		Sleep(50);
	}
	//缩小圆的过程
	while (tempR / 1.1 >= p->r)
	{
		clearcircle(p->x, p->y, tempR + 2);  //擦除原来的圆     
		tempR = tempR / 1.1;
		fillcircle(p->x, p->y, tempR);  //重新绘制一个圆 
		p->color = BLUE;
		Sleep(50);
	}

	while (p->r >= 2)//当圆的半径小于等于2时,结束循环
	{
		clearcircle(p->x, p->y, p->r + 2);//擦除旧圆
		p->r = p->r * 0.9;
		fillcircle(p->x, p->y, p->r);//绘制较小的新圆
		Sleep(50);
	}
	clearcircle(p->x, p->y, p->r + 2);//彻底擦除圆
}
void draw_circle(node* p, int n, int m)//绘制p指针指向的圆
{
	node* s = p;
	int i = 0;
	while (s->next != p) {
		i++;
		s = s->next;
	}
	//删除结点
	node* q = s->next;
	s->next = q->next;
	free(q);
	while (1) {
		for (int j = 0; j < i; j++) {
			setfillcolor(s->color);
			fillcircle((int)(s->x), (int)(s->y), s->r);
			s->color = BLUE;
			s = s->next;
		}
		//可在此处补充代码,显示圆的提示文字
		print(n);//调用打印提示文字的函数
		/*Sleep(500);*/
		for (int i = 0; i < m - 1; i++) {
			s = s->next;
			setfillcolor(GREEN);//指针指向的圆变成绿色
			fillcircle(s->x, s->y, s->r);
			Sleep(500);
			setfillcolor(BLUE);
			fillcircle(s->x, s->y, s->r);
			
		}
		//剩下最后一个圆
		if (i == 1) {
			TCHAR b[] = _T("最终BOSS是:");
			TCHAR c[100];
			outtextxy(-60, 0, b);
			_stprintf(c, _T("%d"), s->num);
			outtextxy(35, 0, c);
			cout << endl;
			_getch();
			break;
		}
		//删除结点
		node* q = s->next;
		s->next = q->next;
		deleteCircle(q);
		i--;
		Sleep(600);
		getbkcolor();
		//cleardevice();
	}

}
void trans(link head) {
	link p = head;
	p->color = BLUE;
	while (p->next != head) {
		p->next;
	}
	while (p->next != p) {
		for (int i = 0; i < m; i++) {
			p = p->next;
			p->color = BLUE;
		}
		/*deleteCircle(p->next);*/
		node* s = p->next;
		p->next = s->next;
	}
}
void main()
{
	printf("请分别输入圆的个数和删除数:", n, m);
	scanf("%d %d", &n, &m);
	link head = creat_link(n);
	initWin();
	draw_circle(head, n, m);//绘制p指针指向的圆
	Sleep(1000);
	//deleteCircle(p);//p指针所指向的节点,原地缩小直至消失
	trans(head);
	while (1);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值