-
个人简介
http://192.168.8.121:8888/user/199 这个人很。。。
//我的高精度加法 int hs(string a,string b) { string c; int a1=a.size(),b1=b.size(),as[5001]={},bs[5001]={},nb[5001]={},slc; for(int i=0;i<a1;i++)as[a1-i-1]=a[i]-'0'; for(int i=0;i<b1;i++)bs[b1-i-1]=b[i]-'0'; if(a1>b1)slc=a1; else slc=b1; for(int i=0;i<slc;i++) { nb[i]+=as[i]+bs[i]; nb[i+1]=nb[i]/10; nb[i]%=10; } if(nb[slc])slc++; for(int i=slc-1;i>=0;i--) { c+=nb[i]+'0'; } h=s; s=c; }
快读模板
void read(long long &x){ long long f=1;x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} x*=f; }
~垃圾~排序
快速排序
int split(int l,int r){ swap(a[l],a[(l+r)/2]); int t=a[l];//以中间作基准 while(l<r){ while(a[r]>t&&l<r)r--;//在左边找大的 if(l<r)a[l++]=a[r];//大的换到右边 while(a[l]<t&&l<r)l++;//在右边找小的 if(l<r)a[r--]=a[l];//小的换到左边 } a[l]=t; return l; } void q_sort(int l,int r){ if(l>=r)return; int mid=split(l,r); q_sort(l,mid-1); q_sort(mid+1,r); }
归并排序
void merge(int L1,int R1,int L2,int R2){ int az=L1,bz=L2,cz=L1; int c[100010]={}; while(az<=R1&&bz<=R2){ if(a[az]>a[bz])c[cz++]=a[bz++]; else c[cz++]=a[az++]; } while(az<=R1)c[cz++]=a[az++]; while(bz<=R2)c[cz++]=a[bz++]; for(int i=L1;i<=R2;i++)a[i]=c[i]; } void msort(int l,int r){ if(l>=r)return; int mid=(l+r)/2; msort(l,mid); msort(mid+1,r); merge(l,mid,mid+1,r); }
上二分学的~唯一有用的~东西:
lower_bound(首地址,尾地址,值);//第一个大于等于值的下标 upper_bound(首地址,尾地址,值);//第一个大于值的下标 nth_element(数组名,数组名+第k小元素,数组名+元素个数)
~每次都会写错~的双端队列和冲锋枪:
deque<int> dq;//声明一个队列dq,用于存储int型变量 dq.push_front(x);//将表达式x的值插入队首 dq.push_back(x);//将表达式x的值插入队尾 dq.pop_front();//弹出队首元素 dq.pop_back();//弹出队尾元素 dq.clear();//清空队列 x=dq.front();//获取队首元素的值,并赋值给x x=qu.back();//获取队尾元素的值,并赋值给x dq.empty();//判断队列dq是否为空,若为空则返回true dq.size();//返回队列dq中存储的元素的个数 vector<int> v; // 声明一个向量 v,用于存储 int 型变量 v.push_back(x); // 将表达式 x 的值存入向量末尾 v.pop_back(); // 删除向量的末尾元素 x = v.front(); // 获取首元素的值,并赋给变量 x x = v.back(); // 获取尾元素的值,并赋给变量 x v.empty(); // 判断向量 v 是否为空,若为空则返回 true v.size(); // 返回向量 v 中存储的元素的个数 v.clear(); // 清空向量
我最讨厌的高精(函数包装,复制即可食用):
string add(string s1,string s2){//加法 long long a[10010]={},b[10010]={},c[10010]={}; long long la=s1.length(),lb=s2.length(),lc=max(la,lb),x=0; string ans=""; for(int i=0;i<la;i++)a[i]=s1[la-i-1]-'0'; for(int i=0;i<lb;i++)b[i]=s2[lb-i-1]-'0'; for(int i=0;i<lc;i++){ c[i]=a[i]+b[i]+x; x=c[i]/10; c[i]=c[i]%10; } if(x)c[lc++]=1; for(int i=lc-1;i>=0;i--)ans+=(c[i]+'0'); return ans; } string sub(string s1,string s2){//减法 long long a[10010]={},b[10010]={},c[10010]={}; long long la=s1.length(),lb=s2.length(),lc=max(la,lb),x=0,f=0; string ans=""; if((s1 < s2 && s1.length() == s2.length()) || s1.length() < s2.length()){ f=1; string t=s1; s1=s2; s2=t; swap(la,lb); cout<<'-'; } for(int i=0;i<la;i++)a[i]=s1[la-i-1]-'0'; for(int i=0;i<lb;i++)b[i]=s2[lb-i-1]-'0'; for(int i=0;i<lc;i++){ c[i]=a[i]-b[i]-x; if(c[i]<0){ x=1; c[i]+=10; }else x=0; } while(c[lc-1]==0&&lc>1)lc--; for(int i=lc-1;i>=0;i--)ans+=(c[i]+'0'); return ans; } string mul(string s1,string s2){//乘法 long long a[10010]={},b[10010]={},c[20010]={}; long long la=s1.length(); long long lb=s2.length(); long long lc=la+lb; string ans=""; for(int i=0;i<la;i++) a[i]=s1[la-1-i]-'0'; for(int i=0;i<lb;i++) b[i]=s2[lb-1-i]-'0'; for(int i=0;i<la;i++){ for(int j=0;j<lb;j++){ c[i+j]+=a[i]*b[j]; c[i+j+1]+=c[i+j]/10; c[i+j]%=10; } } while(c[lc-1]==0&&lc>1){ lc--; } for(int i=lc-1;i>=0;i--) ans+=(c[i]+'0'); return ans; } string div(string s,int b){//高精除低精 int n,a[101000],c[101000],la,lc; la=s.length(),lc=0; for(int i=0;i<la;i++)a[i]=s[i]-'0'; long long x=0; string ans=""; for(int i=0;i<la;i++){ c[i]=(x*10+a[i])/b; x=(x*10+a[i])%b; } while(c[lc]==0&&lc+1<la) lc++; for(int i=lc;i<la;i++)ans+=(c[i]+'0'); return ans; } //高精除高精忒麻烦了懒得写
七类~费脑子~的贪心(sort!)
1. 最优装载 (P2676)
2. 部分背包 (P2240)
3. 乘船问题 (P1094)
4. 交换类贪心 (P1080)
5. 不相交区间 (P1803)
6. 区间选点 (P1250)
7. 区间覆盖 (P1589)
~超级费脑子~的动态规划
重点:状态转移方程!
最长上升子序列方程:if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1)
最长公共子序列方程:if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1,else dp[i][j]=max(dp[i-1][j],dp[i][j-1])
最大子段和方程:dp[i]=max(a[i],dp[i-1]+a[i])
~前缀差分懒得写~
补充:Dilworth 定理=最长上升的子序列的个数=最长不下降子序列的条数
背包
01背包模板:
//n=物品总数,c=背包容量,w[i]=第i个物品的重量,v[i]=第i个物品的价值 for(int i=1;i<=n;i++){//前i个物品 for(int j=c;j>=w[i];j--){//重量为j dp[j]=max(dp[j],dp[j-w[i]]+v[i]);//dp[j](dp[i][j])=前i个物品背包重量为j的最大价值 } }
对于一个物品,只有选或不选两种情况不选就是前i-1个物品加起来的价值,那么就等于dpj,而选的话就是前i-1个物品加上第i个物品的价值, 那么就等于dp[j]+vi,但是在i-1个物品中背包重量为j的情况下背包可能被装满了,所以要牺牲w[i]的空间来装第i个物品,那么背包重量就得改成j-w[i],整个就是dp[j-w[i]]+vi,选或不选两种情况求个最大值就行了,所以状态转移方程就是dp[j]=max(dp[j],dp[j-w[i]]+v[i]) 而j的循环是倒着写的,是因为倒着写每一个重量不会被多次访问
完全背包模板:
for(int i=1;i<=n;i++){//前i个物品 for(int j=w[i];j<=c;j++){//重量为j dp[j]=max(dp[j],dp[j-w[i]]+v[i]); }
完全背包就是01背包的变形,你可以一直选这一个物品.既然可以一直选,那循环就要正着写,因为前面的状态可以被多次访问
多重背包模板:
for(int i=1;i<=n;i++){//前i种物品 for(int j=c;j>=w[i];j--){//重量为j for(int k=0;k<=t[i]&&k*w[i]<=j;k++){//第i种物品选k个,t[i]表示第i种物品有几个 dp[j]=max(dp[j],dp[j-k*w[i]]+k*v[i]); } } }
多重背包也是01背包的变形,种选和不选两种情况变成了选几个 ,所以要用一个循环k来表示选几个
~巨恶心~的树
树的定义
树,是由n(n\ge0)n(n≥0)个结点构成的非线性,具有层次关系的有限集合。
当n=0n=0时,这棵树被称为空树。
当n\ne0n=0时,这棵树被称为非空树,有几个特点:
- 树中仅有一个被称为根的结点
- 除根节点外,其余结点可以划分成多个不相交子树
树的一些术语
- 子结点:对于某一个结点的子树的根叫做子节点
- 父结点:对于他的子节点来说叫做父节点
- 兄弟结点:具有相同父结点的结点互称为兄弟结点
- 结点的度:其子节点的个数
- 树的度:所有结点的度的最大值
- 叶结点:度为0的结点,也就是没有子节点的结点
- 分支结点:度不为0的结点,也就是有子节点的结点
- 结点层次:根结点在第一层,其他结点=其父结点+1
- 树的深度:所有结点的最大层数
- 结点高度:叶结点高度为1,其他节点=max(其所有子节点高度)+1
- 树的高度:等于根的高度
- 路径与路径长度:对于两个结点n和m之间所经过的结点称为结点n到m的路径,其长度为该路径包含的边的数量
~难上加难~的二叉树
性质
- 一棵二叉树第ii层的最大结点数为2^{i-1},i>12i−1**,i>**1
- 一颗深度为ii的最大结点总数为2^i-1,i>12i−1**,i>**1
- 对任何非空的二叉树,若n_0n0表示叶节点的个数,n_2n2是度为2的非叶节点的个数,那么两者满足关系:n_0=n_2+1n0=n2+1
遍历(dfs)
先序:根节点\to→左子树\to→右子树
code:
void dfs(int x){ if(x==0)return; cout<<x<<" "; dfs(a[x].l); dfs(a[x].r); }
中序:左子树\to→根节点\to→右子树
code:
void dfs(int x){ if(x==0)return; dfs(a[x].l); cout<<x<<" "; dfs(a[x].r); }
后序:左子树\to→右子树\to→根节点
code:
void dfs(int x){ if(x==0)return; dfs(a[x].l); dfs(a[x].r); cout<<x<<" "; }
二叉搜索树
定义:左子树<(\le)**<(≤)根节点<(\le)<(≤**)右子树
中序遍历二叉搜索树是非下降的
图(吐)论
图的定义
一个图G是一个二元组,即序偶<V,E>,或记作G=<V,E> ,其中V是有限非空集合,称为G的顶点集,V中的元素称为顶点或结点;E称为 G的边的集合,所有的边ei都属于E,都有v中的结点与之对应,称ei为 G的边。
图的基本概念/术语
- 无向图:每条边都是无向边的图。
- 有向图:每条边都是有向边的图。
- 平凡图:仅有一个结点而没有边构成的图。
- 自环:若一条边所关联的两个结点重合,则称此边为自环。
- 邻接:关联于同一条边的两个点 和 称为邻接的;关联于同一个点的两条边 和 是邻接的(或相邻的)。
- 路径:若顶点,则称从顶点vi0到vin存在一条路径。
- 路径长度:路径上的边数。
- 简单路径:若路径上的顶点除vi0和vin可以相同外,其它顶点都不相同。
- 回路或环:起点和终点相同的简单路径。
- 根:有向图中,若存在一顶点v,从该顶点有路径可以 到图中其它所有顶点,则称此有向图为有根图,v 称为图的根。
- 完全图:若图中各个顶点都与除自身外的其他顶点有关系,这样的无向图称为完全图(如图a))。同时,满足此条件的有向图则称为有向完全图(图b))。
## 图的存储方式
邻接矩阵
一般用一个二维数组mp来存储
mp[i][j]表示i和j之间有没有边
//无向图 #include<bits/stdc++.h> using namespace std; int mp[1010][1010]; int n,m; int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; mp[x][y]=1;//x和y之间有一条边 mp[y][x]=1;//无向图,反着再存 } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<mp[i][j]<<" ";//如果i与j相邻,则输出1,否则输出0 } cout<<endl; } return 0; }
邻接表
一般用二维vector存储
v[x]存的是与x相邻的点
v[x][y]表示x与y相邻
邻接表可以方便求出每个点的出度
#include<bits/stdc++.h> using namespace std; vector<int>mp[1010]; int n,m,; int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; mp[x].push_back(y);//x与y之间有一条边,也就是x与y相邻 mp[y].push_back(x);//无向图再反着存 } for(int i=1;i<=n;i++){ sort(mp[i].begin(),mp[i].end()); cout<<mp[i].size()<<" ";//i的出度 for(int j=0;j<mp[i].size();j++){ cout<<mp[i][j]<<" ";//与i连接的点 } cout<<endl; } return 0; }//感谢"一行"大佬的逼急
1.数据类型: (1)整数类:short;int;long;long long; (unsigned)//希望有unsigned long long long long long long long...... (2)浮点型:float;double; (3)其他类:bool;char;string;struct(用于定义数据类型); 2.变量(数组、函数、结构体等) 命名规则: (1)只能有字母、数字和_; (2)数字不能开头; (3)名称严格区分大小写,且不能重复; 3.编程中的结构: (1)顺序结构; //顺序结构yyds (2)分支结构: if(){ } else { } switch(){ } ?: (3)循环结构: while(){ } do{ }while() for(;;) { } (4)循环跳转: break 从break语句开始,退出当前循环 continue 从continue语句开始,跳过本次循环 4.数组:一个存储多个数据的变量的集合。 (1)数组下标:从0开始,到size()-1结束. (2)除char[]外,不能直接输入和输出 (3)初始化的方式a[]={0} ; (4)二维数组的定义:如果一维数组中的元素又是一个数组,先行后列。 5.字符数组:char a[101] ; (1)求长度: strlen(a) (2)带空格的输入:cin.getline(a,101); (3) 字符串连接:strcat(a,b); 将B连接在A的后面 字符串复制:strcpy(a,b); 将B复制给A 6.字符串string:string a; (1)求长度: a.length(); (2)带空格的输入:getline(cin,a); (3) 字符串连接:a+=b; 将B连接在A的后面 字符串复制:a=b; 将B复制给A 字符串截取:s=s.substr(a,b) ; 从下标a开始截取b个字符 字符串插入:s.insert(a,b) ; 在下标a前插入字符串b 字符串查找:s.find(a); 在字符串s中查找字符串a,找到返回第一位字符的下标, 未找到返回unsigned long long的最大值 7.函数: (1)包含:函数名、函数的参数及数据类型、函数的返回值类型(void)、函数体 (2)常用函数:max(a,b); min(a,b); 要求a,b数据类型相同 整数:abs(a); 浮点数:fabs(a); 数据类型区别 sqrt(a); pow(a,b); 返回值为double类型 sort(a,a+n); 注意下标区别 swap(a,b); 无特殊要求。 memset(a,0,sizeof(a)); 数组初始化 (3)自定义函数: (1)质数判断:时间复杂度为 根号n。 int zs(int x){ if(x<=2) return 0; for(int i=2;i*i<=x;i++) if(x%i==0) return 0; return 1; } (2)数字翻转 int fz(int x){ int a=0; while(x) { a=a*10+x%10; x/=10; } return a;} (3)进制转换 (十进制转二进制:递归实现) void zh(int x) { if(x==0) return ; zh(x/2); cout<<x%2; } (4)递归 (fib) int fib(int x){ if(x<=2) return 1; return fib(x-1)+fib(x-2); } 8.进制转换与原反补码 (1)进制转换:模除法。 (2)特殊的进制转换: (1)二进制与八进制: 二转八:二进制从最低位开始每3位转换为一个八进制的1位,顺序书写即可。 八转二: 八进制的每位转换成一个3位的二进制数,顺序书写即可。 (2)二进制与十六进制: 二转十六:二进制从最低位开始每4位转换为一个十六进制的1位,顺序书写即可。 十六转二:十六进制的每位转换成一个4位的二进制数,顺序书写即可。 (3) 原码:用最高位表示数字的符号,0为正数,1为负数 反码:正数不变,负数除符号位外,全部取反 补码:正数不变,负数为反码+1 9.运算优先级 () 大于! ++ -- 大于 * / % 大于 + - 大于 >> << 大于 > >= < <= 大于 == != 大于 && 大于 || 大于 = += -=... 10.输入与输出 (1)cin 与 cout iostream (2)scanf 与 printf cstdio (3)速度:scanf/printf快于cin/cout '\n'快于endl (4) %d-int/bool %f-float %lf-double %lld-long long %c-char %s-char[] %u-unsigned int %llu-unsigned long long %5d-整数至少5位场宽,右对齐 %-5d-整数至少5位场宽,左对齐 %5s-字符串场宽至少为5,右对齐 %-5s-字符串场宽至少为5,左对齐 %5.3s-字符串从右往左截取3位,场宽5,右对齐 %-5.3s-字符串从右往左截取3位,场宽5,左对齐 %5.3lf-保留3位,场宽5,右对齐 %-5.3lf-保留3位,场宽5,左对齐 iomanip cout<<fixed<<setprecision(3)<<a; 保留3位小数 11.位运算: (1) & 二进制中,有0则为0 。 if(x%2==1)相当于 if(x&1==1) (2) | 二进制中,有1则为1 。 (3) ^ 二进制中,相同为0,不同为1 。a^a=0 a^0=a (4) ~ ~a=-a-1 (5) >> a>>=1相当于a/=2 (6) << a<<=1相当于a*=2 12.排序: (1)冒泡:for(i 表示轮) for(j 表示下标) 比较与交换 (2)选择:for(i 表示轮) 找最小(大)值, 与第i个进行交换 (3)插入:for(i 表示轮) 把当前元素依次向前对比和交换,比其小则停止 (4)桶排:用数组下标进行排序的方式 (5)快排:sort(a,a+n) (6)结构体排序:使用struct 和 sort进行排序,需要自定义cmp函数 13.高精度: (1)加法和减法:用数组的每一位存数字的每一位。 (2)步骤: 存储-转换-计算-特判-输出 14.递推与递归: (1)递推用循环、递归用函数 (2)递推关系与初始条件 15.文件流//真的? (1) freopen("1.in","r",stdin); (2) freopen("1.out","w",stdout);
感谢不知名大佬的逼急
€‘‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š››œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ 贪吃蛇
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <time.h> #include <windows.h> #include <string.h> // 定义标记上下左右的明示常量 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define ESC 5 #define FOOD 10 // 定义表示位置的结构体类型 typedef struct snake{ int x; int y; struct snake *next; }snake; // 定义全局变量 int score = 0; // 当前得分 int speed = 200; // 存储当前速度 int status; snake *tail, *head; // 存储蛇头蛇尾 snake *food, *q;// q用于遍历链表 HANDLE hOUT; void gotoxy(int x, int y); // 设置光标位置 int choice(void); // 载入游戏界面 int color(int c); // 设置字体颜色 void printGame(void); // 打印游戏界面 void printSnake(void); // 打印蛇身 void printFood(void); // 打印食物 void printTips(void); // 打印提示 void snakeMove(void); // 主操作函数 int biteSelf(void); // 判断是否咬到了自己 int encounterWall(void); // 判断是否撞墙 void keyboardControl(void); // 获取击键 void speedUp(void); // 加速 void speedDown(void); // 减速 int endGame(void); // 结束函数; char *s_gets(char *st, int n); // 读取字符 void frees(snake *); // 释放内存 int main(int argc, char *argv[]){ while (1) { if (choice() == 1) keyboardControl(); else { gotoxy(5, 15); printf("按任意键返回"); getchar(); // 去除前一个前导换行 while (1) { if (getchar()) { system("cls"); break; } } } } frees(head); return 0; } void gotoxy(int x, int y) { COORD c; c.X = x; c.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); } int choice(void) { int yourchoice; // 画出界面 gotoxy(35, 5); color(11); printf("\t贪吃蛇大作战\n"); printf("\n\n"); color(13); printf("\t\t★★★★★★★★ Snake!"); printf("\t\t★★★★★★★★ Snake!"); gotoxy(25, 15); color(12); printf("1.进入游戏\t2.查看说明\t3.退出游戏\n"); color(11); printf("请选择:"); scanf("%d", &yourchoice); switch (yourchoice) { case 1: system("cls"); // 初始化 printGame(); printSnake(); printFood(); break; case 2: system("cls"); printTips(); break; case 3: system("cls"); gotoxy(30, 10); color(11); printf("Bye!"); exit(0); default: system("cls"); printf("没有此序号,请输入1,2或3\n"); Sleep(2000); system("cls"); } return yourchoice; } int color(int c) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色 return 0; } void printGame() { int i, j; gotoxy(5, 5); printf("游戏载入中...请稍后"); Sleep(2000); system("cls"); // 打印上下界面 for (i = 0; i <= 50; i += 2) { gotoxy(i, 0); printf("□"); gotoxy(i, 25); printf("□"); } // 打印左右界面 for (i = 0; i <= 25; i += 1) { gotoxy(0, i); printf("□"); gotoxy(50, i); printf("□"); } // 打印中间网格 for (i = 1; i <= 24; i += 1) { for (j = 2; j <= 48; j += 2) { gotoxy(j, i); color(11); printf("■"); } } // 打印右侧的规则和计分栏 gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); gotoxy(60, 15); printf("用↑ ↓ ← →分别控制蛇的移动\n"); gotoxy(60, 18); printf("每次获取食物加10分 按下F1加速,F2减速,空格暂停\n"); gotoxy(60, 20); printf("不能撞墙和咬到自己!"); gotoxy(60, 22); printf("速度不低于100,不高于300"); } void printSnake(void) { int i; // 设定蛇尾(16,13),头插入,初始向右 tail = (snake*)malloc(sizeof(snake)); tail->x = 16; tail->y = 13; tail->next = NULL; // 设定初始蛇长是4 for (i = 1; i <= 4; i++) { head = (snake*)malloc(sizeof(snake)); head->next = tail; head->x = 16 + 2 * i; head->y = 13; tail = head; // 头成为尾 } // 输出蛇身 while (tail->next) { gotoxy(tail->x, tail->y); color(14); printf("★"); tail = tail->next; } } void printFood(void) { srand((unsigned)time(NULL)); // 利用时钟修改种子 food = (snake*)malloc(sizeof(snake)); food->x = 1; // 初始化x坐标 while (food->x % 2 && food->x) { food->x = rand() % 46 + 2;// 2-48 } food->y = rand() % 23 + 1; // 1-24 q = head; // 不改变头遍历链表 while (q->next) { if (q->x == food->x && q->y == food->y) { free(food); printFood(); } else { gotoxy(food->x, food->y); color(12); printf("●"); break; } } } void printTips(void) { color(11); printf("***********Tips************\n"); printf("1.采用合理的速度可以获得更高的分数哦!\n"); printf("2.一定不要撞到自己或者两边的墙!\n"); printf("3.游戏过程中按ESC退出游戏!\n"); } void snakeMove(void) { snake *snakenext; snakenext = (snake*)malloc(sizeof(snake)); if (biteSelf()) { gotoxy(60, 11); printf("咬到自己啦!"); free(snakenext); Sleep(1500); system("cls"); exit(0); } else if (encounterWall()) { gotoxy(60, 11); printf("撞到墙啦!"); free(snakenext); Sleep(1500); system("cls"); exit(0); } else { // 前两个条件判断完成才开始移动 Sleep(350 - speed); if (status == UP) { snakenext->x = head->x; snakenext->y = head->y - 1; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } else if (status == DOWN) { snakenext->x = head->x; snakenext->y = head->y + 1; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } else if (status == LEFT) { snakenext->x = head->x - 2; snakenext->y = head->y; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } else if (status == RIGHT) { snakenext->x = head->x + 2; snakenext->y = head->y; snakenext->next = head; head = snakenext; q = head; if (snakenext->x == food->x && snakenext->y == food->y) { while (q) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } score += FOOD; gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); printFood(); } else { while (q->next->next) { gotoxy(q->x, q->y); color(14); printf("★"); q = q->next; } gotoxy(q->next->x, q->next->y); color(11); printf("■"); free(q->next); q->next = NULL; } } } } int biteSelf(void) { int x = 0; // 默认未咬到自己 q = head->next; // 遍历蛇身 while (q->next) { if (q->x == head->x && q->y == head->y) { x = 1; } q = q->next; } return x; } int encounterWall(void) { int x = 0; // 默认未撞到墙 if (head->x == 0 || head->x == 50 || head->y == 0 || head->y == 25) x = 1; return x; } void keyboardControl(void) { status = RIGHT; // 初始蛇向右移动 while (1) { if (GetAsyncKeyState(VK_UP) && status != DOWN) // GetAsyncKeyState函数用来判断函数调用时指定虚拟键的状态 { status = UP; //如果蛇不是向下前进的时候,按上键,执行向上前进操作 } else if (GetAsyncKeyState(VK_DOWN) && status != UP) // 如果蛇不是向上前进的时候,按下键,执行向下前进操作 { status = DOWN; } else if (GetAsyncKeyState(VK_LEFT) && status != RIGHT) // 如果蛇不是向右前进的时候,按左键,执行向左前进 { status = LEFT; } else if (GetAsyncKeyState(VK_RIGHT) && status != LEFT) // 如果蛇不是向左前进的时候,按右键,执行向右前进 { status = RIGHT; } if (GetAsyncKeyState(VK_SPACE))// 空格暂停 { while (1) { Sleep(300); if (GetAsyncKeyState(VK_SPACE)) // 再次按空格改变状态 { break; } } } else if (GetAsyncKeyState(VK_ESCAPE)) { status = ESC; // 按esc键,直接到结束界面 if (endGame()) { Sleep(500); system("cls"); break; } } else if (GetAsyncKeyState(VK_F1)) // 按F1键,加速 { speedUp(); gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); } else if (GetAsyncKeyState(VK_F2)) // 按F2键,减速 { speedDown(); gotoxy(60, 13); printf("当前分数:%d分,当前速度%d", score, speed); } snakeMove(); } } void speedUp(void) { if (speed <= 280) speed += 20; } void speedDown(void) { if (speed >= 120) speed -= 20; } int endGame(void) { char x = 0; char judge[5]; getchar(); gotoxy(60, 9); printf("确定退出吗?(Yes/No)"); gotoxy(60, 11); s_gets(judge, 5); if (strcmp(judge, "Yes") == 0) { Sleep(250); system("cls"); gotoxy(40, 11); printf("\tBye!"); x = 1; } else x = 0; return x; } char *s_gets(char *st, int n) { char *ret_val; char *find; gotoxy(60, 11); ret_val = fgets(st, n, stdin); if (ret_val) { find = strchr(st, '\n'); if (find) *find = '\0'; else while (getchar() != '\n') continue; } return ret_val; } void frees(snake *s) { snake *current = s; while (current) { current = s; s = current->next; free(current); } }
-
通过的题目
-
最近活动
-
最近编写的题解
题目标签
- 基础算法
- 31
- 动态规划
- 23
- 课课通
- 16
- 其他
- 15
- 数据结构
- 14
- 普及组
- 12
- 数组
- 11
- 提高组
- 9
- 排序
- 8
- 递推
- 8
- 队列
- 8
- 模拟
- 7
- 图结构
- 7
- 背包
- 7
- 基础数据结构
- 7
- 搜索
- 6
- 字符串
- 6
- 函数
- 6
- 贪心
- 5
- 分治
- 5