C++GUI基础学习笔记-实现倒序排列算法动画

文章目录:

一:题目要求

二:相关代码 

1.倒序排序算法动画项目代码

2.冒泡排序

3.题目命令行形式

三:网上资源

四:基础知识

1.颜色

2.形状 

3.画笔

4.画刷

5.画坦克


        

一:题目要求

C++GUI实现逆序排列
77页
	解决一些小的n值谜题,将会给你指明正确方向
188页

1.基于Windows GUI(图形用户界面)的应用程序
2.让用户通过观看和操作,理解数据结构和算法的内部过程
3.设计相应的剧情、玩法、视觉元素、背景音乐与事件音效等
4.动画展示:数据结构和算法的每一步变化过程

题目

问题:
    有n张卡片排成一行,并且有n个不同的数字写在卡片上(每张卡片上一个),使得卡片呈降序排列状态
    现在允许你交换任何一对卡片的位置,只要它们之间只有一张卡片即可
    对于什么样的n值,在这样一组操作序列以后,能使得卡片呈升序排列?
    如果这样n值存在的话,请设计使得交换次数最小的算法

解析:
    n张卡片排列成一排,每个都有数字,初始为降序
    交换一对卡片(中间必须隔一张),那么经过多少次交换成升序排列
    求:如果存在n  需要交换多少次

答案


二:相关代码 

1.倒序排序算法动画项目代码

C++倒序排列算法动画 

#include <iostream>
#include <stdio.h>	//头文件
#include <easyx.h>
#include <stdlib.h>
#include <windows.h>
#include <graphics.h>				//图形库头文件
#include <conio.h>					//案件操作防止闪屏 getch
#include <mmsystem.h>				//多媒体库
#pragma comment(lib,"winmm.lib")	//加载静态库文件
#pragma warning(default: 4996)		//鼠标交互 将报警设置为默认
#include <ctime>
using namespace std;


int n =9;			//卡片数
int liu=(n+1)/2;	//卡片数和位置数关系

void fristgui(); //第一界面按钮
void bk();		 //第二界面背景
void dongtai();	 //第二界面按钮
void loadResource2();
void loadResource1();
void title();
void endnum();

 

 
/**第一界面按钮**/
void fristgui()
{
	//1.移动矩形
		for(int i=80;i<630;i++)
		{
			for (int j = 20; j < 300; j++)
			{
				solidrectangle(20,200,i,j);
			}
		}

 
	//2.准备文字
	char beginString[]="开始排列";
	char closeString[]="退出排列";
	char tishiString[]="排列说明";
	char tipsString[]="倒序排列算法";
	char nameString[]="物联网3班刘鑫磊";
 
	//3.界面布局
	//set设置 fill填充 color颜色 LIGHT:淡 
	setfillcolor(CYAN);
 
	//4.画按钮矩形
	solidrectangle(240,40,380,90);
	solidrectangle(240,100,380,150);
	solidrectangle(240,160,380,160+50);
 
	//5.文字布局
	settextcolor(BLACK);
	setbkmode(TRANSPARENT);	//去掉文字背景
	settextstyle(30,0,"楷体");
	outtextxy(240+15,40+10,tishiString);
	outtextxy(240+15,100+10,beginString);
	outtextxy(240+15,160+10,closeString);
	
	outtextxy(255,50,tishiString);
	outtextxy(220,250,tipsString);
	outtextxy(200,310,nameString);
 
	//6.鼠标交互
	while(1)
	{
		MOUSEMSG m = GetMouseMsg();
		if(m.x>=240	&&	m.x<=380 && m.y>=100 && m.y<=150)
		{
			setlinecolor(RED);
			rectangle(240-5,100-5,380+5,150+5);
			//开始游戏
			if(m.uMsg==WM_LBUTTONDOWN)
			{
				break;
			}
		}else if (m.x>=240 && m.x<=380 && m.y>=160 && m.y<=210)
		{
			setlinecolor(RED);
			rectangle(240-5,160-5,380+5,210+5);
			//退出游戏
			if(m.uMsg==WM_LBUTTONDOWN)
			{
				exit(0);
			}
		}else if (m.x>=240 && m.x<=380 && m.y>=40 && m.y<=90)
		{
			setlinecolor(RED);
			rectangle(240-5,40-5,380+5,90+5);
			//游戏说明
			if(m.uMsg==WM_LBUTTONDOWN)
			{
				setbkmode(0);   //去掉文字背景
    			settextcolor(BLUE);	//设置文字颜色
    			settextstyle(15,0,TEXT("楷体"));		//(高,宽<0为自适应>,字体)
				outtextxy(10,350,"排列说明:");
				outtextxy(70,370,"n张卡片排列成一排,每个都有数字,初始为降序交换一对卡片(中间必须隔一张),");
				outtextxy(70,390,"那么经过多少次交换成升序排列,如果存在这样n张卡片,那么需要交换多少次");
			}
		}
		else
		{
			setlinecolor(WHITE);
			rectangle(240-5,100-5,380+5,150+5);
			rectangle(240-5,160-5,380+5,210+5);
			rectangle(240-5,40-5,380+5,90+5);
		}
	}
}
 
 
/**第二界面背景**/
void bk()
{
	//1.背景
			//一:图片
			//1.创建一个窗口	属性:宽高 658 369
			initgraph(1300,800);
			//2.显示图片到窗口上面,为图片取名字
			IMAGE bei;
			//3.把名字分配给图片
			loadimage(&bei,"bei.jpg",1300,800);
			//显示图片:图片坐标
			putimage(0,0,&bei);

	 //2.音乐
			//播放音乐
			//打开	alias起别名
			mciSendString("open 1.mp3 alias music",0,0,0);
			//播放
			mciSendString("play music repeat",0,0,0);


	
	//3.移动条	
				IMAGE niao;
				//把名字分配给图片
				loadimage(&niao,"brid.jpg",60,60);
				//左
				for (int i = 0; i < 1250; i++)
				{
					putimage(0+i,0,&niao);
					Sleep(1);
				}
 
				//下
				for (int i = 0; i < 798; i++)
				{
					putimage(1250,0+i,&niao);
					Sleep(1);
				}
 
				//右
				for (int i = 0; i < 1250; i++)
				{
					putimage(1250-i,740,&niao);
					Sleep(1);
				}
 
				//上
				for (int i = 0; i < 750; i++)
				{
					putimage(0,750-i,&niao);
					Sleep(1);
				}
}
 
 
/**第二界面按钮**/
void dongtai()
{
	//1.准备文字
	char beginString[]="动态演示";
 
 
	//2.界面布局
	//set设置 fill填充 color颜色 LIGHT:淡 
	setfillcolor(CYAN); //CYAN
 
	//3.画椭圆
	solidellipse(570,180,720,230);
 
 
	//4.文字布局
	settextcolor(BLACK);
	setbkmode(TRANSPARENT);	//去掉文字背景
	settextstyle(30,0,"楷体");
	outtextxy(570+15,180+10,beginString);
 
	//5.鼠标交互
	while(1)
	{
		MOUSEMSG m = GetMouseMsg();
		if(m.x>=570	&&	m.x<=720 && m.y>=180 && m.y<=230)
		{
			setlinecolor(RED);
			rectangle(570-5,180-5,720+5,230+5);
			//开始游戏
			if(m.uMsg==WM_LBUTTONDOWN)
			{
				break;
			}
		}
		else
		{
			setlinecolor(CYAN);
			rectangle(570-5,180-5,720+5,230+5);
		}
	}
}


//第二界面:排序每一步
void loadResource2()
{
	//图片
	LPCTSTR arr[9] = {"one.PNG","two.PNG","three.PNG","four.PNG","five.PNG","six.PNG","seven.PNG","eight.PNG","nine.PNG"};
		//
		int * b = new int[n];
		for(int i=n;i>0;i--) //i  =9 8 7 6 5 4 3 2 1 
		{
			b[n-i] = i;      //n-i=0 1 2 3 4 5 6 7 8   //b
		}
		int y=60;
		//排序
		for (int i=0;i<n-1;i++)//每次最大元素就像气泡一样浮到数组的最后
		{	
			//输出图片数字
			for (int i = 0; i < n; i++)
			{
				IMAGE img;
				//把名字分配给图片
				loadimage(&img,arr[b[i]-1],50,50);//图片 8 7 6 5 4 3 2 1 0
				//显示图片:
				putimage(270+90*i,y+200,&img);
				Sleep(200);
			}
			//向下
			y+=60;
		
			int j;
			if(i%2==0)j=0;		//偶数
			else j=1;			//奇数
			int max_index = j;  //默认最大值
			for(;j<n-i;j+=2)	//依次比较相邻的两个元素,使较大的那个向后移
			{                   //交换
				if(b[j]<b[max_index])
				{
					int temp = b[max_index];
					b[max_index] = b[j];
					b[j] = temp;
					max_index = j;	//当前最大值
				}
			}

		}
}
 
//第二界面:排序动态
void loadResource1()
{
	//正序输出
	LPCTSTR arr[9] = {"one.PNG","two.PNG","three.PNG","four.PNG","five.PNG","six.PNG","seven.PNG","eight.PNG","nine.PNG"};

		int * b = new int[n];
		for(int i=n;i>0;i--)
		{
			b[n-i] = i;
		}

		int y=60;
		//排序
		for (int i=0;i<n-1;i++)//每次最大元素就像气泡一样浮到数组的最后
		{	
			//输出		
			y=60;

			int j;
			if(i%2==0)j=0;		//偶数
			else j=1;			//奇数
			int max_index = j;  //默认最大值
			for(;j<n-i;j+=2)	//依次比较相邻的两个元素,使较大的那个向后移
			{                   //交换
				if(b[j]<b[max_index])
				{
					int temp = b[max_index];
					b[max_index] = b[j];
					b[j] = temp;
					max_index = j;//当前最大值
				}

				for (int i = 0; i < n; i++)
				{
					IMAGE img;
					//把名字分配给图片
					loadimage(&img,arr[b[i]-1],50,50);
					//显示图片:
					putimage(270+90*i,y+50,&img);
					Sleep(200);
				}
			}

		}
	}

//彩色提示标题
void title()
{
	srand((unsigned)time(NULL));
		while(1)    //检测按键函数,输入按键返回1,不输返回0,我们这里要相反的
		{	
			setcolor(RGB(rand()%256,rand()%256,rand()%256));
			settextstyle(50,0,TEXT("楷体"));	
			//RGB是三原色红,绿,蓝,颜色范围是0~255
			outtextxy(480,0,"排序已经完成");
			Sleep(50);
		}
}

void endnum()
{
	//卡片数
		char num3[100];	
		sprintf(num3, "%d", n);
		setbkmode(0);   //去掉文字背景
    	settextcolor(BLACK);	//设置文字颜色
    	settextstyle(25,0,TEXT("楷体"));		//(高,宽<0为自适应>,字体)
		outtextxy(110,65,"存在这样的卡片数(你输入的数)为:");
    	outtextxy(550,65,num3);    //(x,y,内容)  


	//交换次数
		char num1[100];	
		int num2=2*liu+1;	//次数和
		sprintf(num1, "%d",( num2-1)* num2-1/4);
		setbkmode(0);   //去掉文字背景
    	settextcolor(BLACK);	//设置文字颜色
    	settextstyle(25	,0,TEXT("楷体"));		//(高,宽<0为自适应>,字体)
		outtextxy(670,65,"按照规则采用冒泡排序交换次数最小为:");
    	outtextxy(1130,65,num1);    //(x,y,内容)
		outtextxy(1170,65,"次");
}

 
int main()
{
	initgraph(650,420);	//第一界面大小
	setbkcolor(CYAN);	//第一界面颜色
	cleardevice();		//用于图形显示
	fristgui();		    //第一界面按钮 
	
	if (n%2==0)			//判断是不是偶数
		exit(0);

	bk();				//第二界面背景
	endnum();
	loadResource2();	//第二界面依次排序
	dongtai();			//动态按钮
	loadResource1();	//第二界面动态
	
	title();			
	while(1);			//第一界面进入
	_getch();
	closegraph();		
 
	system("pause");
	return 0;
}

2.冒泡排序

//冒泡插入排序
		for (int i=0;i<num-1;i++)//每次最大元素就像气泡一样浮到数组的最后
		{
			for(int j=0;j<num-1-i;j++) //依次比较相邻的两个元素,使较大的那个向后移
			{
				if(a[j]>a[j+1]) //如果条件改为arr[j] >= arr[j+1] 则变为不稳定的排序算法
				{
					int temp=a[j];
					a[j] = a[j+1];
					a[j+1] = temp;
				}
			}
		}

3.题目命令行形式

#include <iostream>
#include <cmath>
using namespace std;
int num;
int a[1000] ;		//定义数组长度
int i,j;		//定义变量


void change()
{
		//冒泡插入排序
		for (int i=0;i<num-1;i++)//每次最大元素就像气泡一样浮到数组的最后
		{
			for(int j=0;j<num-1-i;j++) //依次比较相邻的两个元素,使较大的那个向后移
			{
				if(a[j]>a[j+1]) //如果条件改为arr[j] >= arr[j+1] 则变为不稳定的排序算法
				{
					int temp=a[j];
					a[j] = a[j+1];
					a[j+1] = temp;
				}
			}
		}
}
 
int main(){
    cout <<"请输入元素的个数:";
	cin>>num;
	if(num%2==0)
	{
		cout<<"抱歉偶数不能运行成功!因为没有答案,第1个最大的数永远到不了最后形成倒序"<<endl;
	}else
	{
		int liu=(num+1)/2;
			cout<<"提示:请降序输入数字!"<<endl;
			//键盘循环输入数
			for (i = 0; i < num; i++)
			{
				cout<< "请输入"<<num<<"个整数存到数组,第"<<i+1<<"次输入为:";
				cin >>a[i];
			}
			//输出键盘的个数
			cout<<"你输入的数组为:";
			 for(int i=0;i<num;i++)
				{
					cout<<a[i]<<"  ";
				}	
				  cout<<endl;
		cout << "-----------------------------------------------------"<<endl;
		for (int i = 1; i < num; i++)
		{
			if (i%2==1)
			{
				change();
			}else
			{
				change();
			}
		}
 
		cout<<"其冒泡排序后为:";
				for(int i=0;i<num;i++)
					{
						cout<<a[i]<<"  ";
					}	
				cout<<endl;

	cout<<endl;
	cout<<"如果有"<<num<<"张卡片,那么采用冒泡排序将要交换:"<<2*liu+1<<"次!"<<endl;	
	}
	
	
 
 
	
	system("pause");
	return 0;
}

 

 


三:网上资源

C/C++游戏开发教程:C语言实现—飞翔的小鸟(可视化编程+背景音乐+分数+边界设置+小鸟碰撞) 

【C/C++编程】GUI/GDI绘图技术,图形化编程终极篇!你所看到的一切皆可进行人机交互!_哔哩哔哩_bilibili        图片移动

游戏

C++实战项目007-冒泡排序之游戏贴图

C\C++插入图片,音乐,文字

C++ GUI控件使用与GDI界面库编程


四:基础知识

1.颜色

红色:255,0,0

绿色:0,255,0

蓝色:0,0,255

黄色:255,255,0

紫色:255,0,255

2.形状 

    {//语句块
		hdc = BeginPaint(hWnd, &ps);
		
		//画矩形
		Rectangle(hdc,0,0,200,100);
		//正方形
		Rectangle(hdc,10,10,200,200);
		//画圆
		Ellipse(hdc,200,200,400,400);
		//椭圆
		Ellipse(hdc,300,300,400,100);
		//画线
		MoveToEx(hdc,100,100,NULL);
		LineTo(hdc,300,200);
	}

3.画笔

		//1.画笔
		HPEN hpen1,hpen2,hpen3,hpen4,hpen5;
		//创建画笔第一种方式
		//啥子笔,宽度,颜色	
			//hpen1=CreatePen(PS_SOLID,4,RGB(255,0,0));		//实线		//红色:255,0,0
			//hpen2=CreatePen(PS_DASH,1,RGB(0,255,0));		//虚线		//绿色:0,255,0	1才是虚线大于九不是了
			//hpen3=CreatePen(PS_DASHDOT,1,RGB(0,0,255));	//线点		//蓝色:0,0,255
			//hpen4=CreatePen(PS_DASHDOTDOT,1,RGB(0,0,255));//线点点	//蓝色:0,0,255

		//创建画笔第二种方式
			LOGPEN logPen;
			logPen.lopnStyle=PS_SOLID;
			logPen.lopnWidth.x=5;
			logPen.lopnColor=RGB(255,255,0);	//黄色
			hpen5=CreatePenIndirect(&logPen);
			

		//拿笔
			//SelectObject(hdc,hpen1);
			//SelectObject(hdc,hpen2);
			//SelectObject(hdc,hpen3);
			//SelectObject(hdc,hpen4);
			SelectObject(hdc,hpen5);
		//正方形
		Rectangle(hdc,10,10,200,200);

4.画刷

//2.画刷(填充颜色 一个封闭区域)	白色默认画刷
		//创建画刷
		HBRUSH hBrush1=CreateSolidBrush(RGB(255,0,255));	//紫色
		//拿画刷
		SelectObject(hdc,hBrush1);
		//正方形
		Rectangle(hdc,10,10,200,200);

5.画坦克

#define TANK_WIDTH	40//坦克的宽度
#define TANK_HEIFHT	40//坦克的高度
//坦克
typedef struct _Trank
{
	int x;
	int y;
}Tank;

	//定义坦克
	static Tank tank;

	switch (message)
	{

	case WM_CREATE://窗口创建消息
		{
		//获取窗口的宽和高
			RECT rect;
			GetClientRect(hWnd,&rect);
			tank.x=(rect.right-rect.left)/2;
			tank.y=(rect.bottom-rect.top)- (TANK_HEIFHT/2);
		}
		break;

 

//绘制坦克
void DrawTank(HDC hDC,Tank tank);

//绘制坦克
void DrawTank(HDC hDC,Tank tank)
{
	//画刷
	HBRUSH hBrush=CreateSolidBrush(RGB(255,238,114));
	HBRUSH hOldBrush=(HBRUSH)SelectObject(hDC,hBrush);
	//画矩形
	Rectangle(hDC,tank.x-TANK_WIDTH/2,tank.y-TANK_HEIFHT/2,tank.x+TANK_WIDTH/2,tank.y+TANK_HEIFHT/2);
	SelectObject(hDC,hOldBrush);

}
case WM_KEYDOWN://键盘按下
		switch (wParam)
		{
		case VK_LEFT:
			tank.x -=5;
			break;
		case VK_RIGHT:
			tank.x +=5;
			break;
		case VK_UP:
			tank.y -=5;
			break;
		case VK_DOWN:
			tank.y +=5;
			break;
		}
		//刷新
		InvalidateRect(hWnd,NULL,TRUE);
		break;
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘鑫磊up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值