分享一个约瑟夫环实验,看效果图吧。
首先获取用户输入
根据用户输入,会自动生成相应的约瑟夫环,循环到相应的删除数时,圆变成黄色,并且先变大再逐渐变小直至消失。
下面是完整代码:
#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);
}