用c语言编写,关于24点的程序
#include double fun(double a1,double a2,int b) //加减乘除的函数{switch(b) {case 0:return (a1+a2); case 1:return (a1-a2); case 2:return (a1*a2); case 3:return (a1/a2); } } void main() {int i,j,k,l,n,m,r,save[4],flg=1; double num[4]={1,1,1,1},tem1,tem2,tem3,abc=1111; char sign[5]="+-*/"; printf("输入四个数:"); for(i=0;i13)flg=0;}if(flg) {flg=0;for(i=0;i<4;i++) for(j=0;j<4;j++) if(j!=i) {for(k=0;k<4;k++) if(k!=i&&k!=j) {for(l=0;l<4;l++) if(l!=i&&l!=j&&l!=k) {for(n=0;n<4;n++) for(m=0;m<4;m++) for(r=0;r<4;r++) {tem1=fun(num[i],num[j],n); tem2=fun(tem1,num[k],m); tem3=fun(tem2,num[l],r); if(tem3==24.0) {printf("{(%d%c%d)%c%d}%c%d=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);return;}else if(tem3==-24.0) {printf("{%d%c(%d%c%d)}%c%d=24\n",save[k],sign[m],save[i],sign[n],save[j],sign[r],save[l]);return;}else if(tem3==1.0/24.0) {printf("%d%c{(%d%c%d)%c%d}=24\n",save[l],sign[r],save[i],sign[n],save[j],sign[m],save[k]);return;}else if(tem3==-1.0/24.0) {printf("%d%c{%d%c(%d%c%d)}=24\n",save[l],sign[r],save[k],sign[n],save[i],sign[m],save[j]);return;}else {tem1=fun(num[i],num[j],n); tem2=fun(num[k],num[l],r); tem3=fun(tem1,tem2,m); if(tem3==24.0) {printf("(%d%c%d)%c(%d%c%d)=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);return;}} } } } }}if(!flg) printf("NO ANSWER\n"); }
给我说下这个24点程序的算法,急
首先我们看看程序的主过程main(),第一步,让用户输入四个1-13的数字,这步比较简单。
第二步,见到四个for循环,看起来有点吓人,其实是把这四个数字重新排列组合,获得所有先后排列的次序。
(个人认为这里用for并不是十分好的算法,其实还有更好的,这个以后有机会可以继续讨论)这里主要是把四个数字的下标顺序改变,那么num[i],num[j],num[k],num[t]实际上就有了不同的次序了。
(其实我所说的更好的办法是直接交换它们的值,这样循环的次数可以少得多)。
第三步,把重新排列的四个数字推进treat中进行计算。
res用于设立一个是否能获得计算结果的标记,如果res为0,则表示没有结果。
四个数要进行三步运算才能得出最后结果,所以该过程使用了sum1,sum2,sum3来临时存放这些中间结果。
每两个数之间的计算有+-*/四种,这些将会使用myf来计算。
该函数使用for循环来穷举四个数之间三次运算中每次运算的+-*/四种计算。
如果最后计算出来的结果是24,那么就会使用myprint来打印计算方法。
myf是个用于返回+-*/四种运算的结果的函数。
三个参数中flag标记有五种,分别是加减乘除和被除,其中后面两种,若除数为0就返回30000,以避免出错。
m和n分别是左运算数和右运算数。
例如,如果myf(1,3,4),则返回3-4(即-1)。
myprint的设计比较巧妙。
它用type来表示表达式的结构。
如果用%来表示+-*/中的任意一个运算符,abcd表示四个运算数(这些数字已经在main中被重新排列),那么必然只有a%b%c%d、(a%b)%c%d、a%(b%c)%d等五种。
四个数之间的三个运算符用i,j,k表示,四个运算数用abcd表示。
其中i,j,k取值012345分别是+-*/、负号和被除。
适合初学者的24点游戏C语言源代码
关于二十四点游戏的编程思路与基本算法 漫长的假期对于我来说总是枯燥无味的,闲来无聊便和同学玩起童年时经常玩的二十四点牌游戏来。
此游戏说来简单,就是利用加减乘除以及括号将给出的四张牌组成一个值为24的表达式。
但是其中却不乏一些有趣的题目,这不,我们刚玩了一会儿,便遇到了一个难题——3、6、6、10(其实后来想想,这也不算是个太难的题,只是当时我们的脑筋都没有转弯而已,呵呵)。
问题既然出现了,我们当然要解决。
冥思苦想之际,我的脑中掠过一丝念头——何不编个程序来解决这个问题呢?文曲星中不就有这样的程序吗?所以这个想法应该是可行。
想到这里我立刻开始思索这个程序的算法,最先想到的自然是穷举法(后来发现我再也想不到更好的方法了,悲哀呀,呵呵),因为在这学期我曾经写过一个小程序——计算有括号的简单表达式。
只要我能编程实现四个数加上运算符号所构成的表达式的穷举,不就可以利用这个计算程序来完成这个计算二十四点的程序吗?确定了这个思路之后,我开始想这个问题的细节。
首先穷举的可行性问题。
我把表达式如下分成三类——1、 无括号的简单表达式。
2、 有一个括号的简单表达式。
3、 有两个括号的较复4、 杂表达式。
穷举的开始我对给出的四个数进行排列,其可能的种数为4*3*2*1=24。
我利用一个嵌套函数实现四个数的排列,算法如下:/* ans[] 用来存放各种排列组合的数组 *//* c[] 存放四张牌的数组 *//* k[] c[]种四张牌的代号,其中k[I]=I+1。
用它来代替c[]做处理,考虑到c[]中有可能出现相同数的情况 *//* kans[] 暂存生成的排列组合 *//* j 嵌套循环的次数 */ int fans(c,k,ans,kans,j) int j,k[],c[];char ans[],kans[]; { int i,p,q,r,h,flag,s[4],t[4][4]; for(p=0,q=0;p{ for(r=0,flag=0;r if(k[p]!=kans[r]) flag++; if(flag==j) t[j][q++]=k[p]; } for(s[j]=0;s[j]{ kans[j]=t[j][s[j>; if(j==3) { for(h=0;hans[2*h]=c[kans[h]-1]; /* 调整生成的排列组合在最终的表 达式中的位置 */ for(h=0;hsymbol(ans,h); /* 在表达式中添加运算符号 */ } else { j++; fans(c,k,ans,kans,j); j--; } } } 正如上面函数中提到的,在完成四张牌的排列之后,在表达式中添加运算符号。
由于只有四张牌,所以只要添加三个运算符号就可以了。
由于每一个运算符号可重复,所以计算出其可能的种数为4*4*4=64种。
仍然利用嵌套函数实现添加运算符号的穷举,算法如下:/* ans[],j同上。
sy[]存放四个运算符号。
h为表达式形式。
*/ int sans(ans,sy,j,h) char ans[],sy[];int j,h; { int i,p,k[3],m,n; char ktans[20]; for(k[j]=0;k[j]{ ans[2*j+1]=sy[k[j>; /* 刚才的四个数分别存放在0、2、4、6位 这里的三个运算符号分别存放在1、3、5位*/ if(j==2) { ans[5]=sy[k[j>;/* 此处根据不同的表达式形式再进行相应的处理 */ } else { j++; sans(ans,sy,j--,h); } } } 好了,接下来我再考虑不同表达式的处理。
刚才我已经将表达式分为三类,是因为添加三个括号对于四张牌来说肯定是重复的。
对于第一种,无括号自然不用另行处理;而第二种情况由以下代码可以得出其可能性有六种,其中还有一种是多余的。
for(m=0;mfor(n=m+4;n 这个for循环给出了添加一个括号的可能性的种数,其中m、n分别为添加在表达式中的左右括号的位置。
我所说的多余的是指m=0,n=8,也就是放在表达式的两端。
这真是多此一举,呵呵!最后一种情况是添加两个括号,我分析了一下,发现只可能是这种形式才不会是重复的——(a b)(c d)。
为什么不会出现嵌套括号的情况呢?因为如果是嵌套括号,那么外面的括号肯定是包含三个数字的(四个没有必要),也就是说这个括号里面包含了两个运算符号,而这两个运算符号是被另外一个括号隔开的。
那么如果这两个运算符号是同一优先级的,则肯定可以通过一些转换去掉括号(你不妨举一些例子来试试),也就是说这一个括号没有必要;如果这两个运算符号不是同一优先级,也必然是这种形式((a+-b)*/c)。
而*和/在这几个运算符号中优先级最高,自然就没有必要在它的外面添加括号了。
综上所述,所有可能的表达式的种数为24*64*(1+6+1)=12288种。
哈哈,只有一万多种可能性(这其中还有重复),这对于电脑来说可是小case哟!所以,对于穷举的可行性分析和实现也就完成了。
接下来的问题就是如何对有符号的简单表达式进行处理。
这是栈的一个著名应用,那么什么是栈呢?栈的概念是从日常生活中货物在货栈种的存取过程抽象出来的,即最后存放入栈的货物(堆在靠出口处)先被提取出去,符合“先进后出,后进先出”的原则。
这种结构犹如子弹夹。
在栈中,元素的插入称为压入(push)或入栈,元素的删除称为弹出(pop)或退栈。
栈的基本运算有三种,其中包括入栈运算、退栈运算以及读栈顶元素,这些请参考相关数据结构资料。
根据这些基本运算就可以用数组模拟出栈来。
那么作为栈的著名应用,表达式的计算可以有两种方法。
第一种方法—— 首先建立两个栈,操作数栈OVS和运算符栈OPS。
其中,操作数栈用来记忆表达式中的操作数,其栈顶指针为topv,初始时为空,即topv=0;运算符栈用来记忆表达式中的运算符,其栈顶指针为topp,初始时,栈中只有一个表达式结束符,即topp=1...
编程求计算24点的方法
解法用到的基本思想就是回溯,树的深度为最深为4,树的判断分支为 加减乘除,对不满足条件的解进行剪枝(即当前结果>=24),当到达递归边界(即树的深度为四时)时,即判断当前的结果是否符合条件(=24),符合即找到解,否则继续进行。
参考代码如下:#include#includeusing namespace std;const double MIN=1E-6;void Print(int *Rank,double *FourNum){for(int i=0;icoutcout}void Calculate_24(int *Rank,int *FourNum,char *Oper,int i,int j,int k,bool &def){double res=0;switch(i){case 0:res=FourNum[Rank[0]]+FourNum[Rank[1]];break;case 1:res=FourNum[Rank[0]]-FourNum[Rank[1]];break;case 2:res=FourNum[Rank[0]]*FourNum[Rank[1]];break;case 3:res=FourNum[Rank[0]]/FourNum[Rank[1]];break;}switch(j){case 0:res=res+FourNum[Rank[2]];break;case 1:res=res-FourNum[Rank[2]];break;case 2:res=res*FourNum[Rank[2]];break;case 3:res=res/FourNum[Rank[2]];break;}switch(k){case 0:res=res+FourNum[Rank[3]];break;case 1:res=res-FourNum[Rank[3]];break;case 2:res=res*FourNum[Rank[3]];break;case 3:res=res/FourNum[Rank[3]];break;}if(fabs(res-24)>MIN)return;else{def=true;for(int num=1;num{switch(num){case 1:coutbreak;case 3:coutbreak;case 5:coutbreak;case 7:coutbreak;case 2:coutbreak;case 4:coutbreak;case 6:coutbreak;}}cout}}void SearchTree(int Depth,int *Rank,int *FourNum,char *Oper,bool &def){int i,j,k;if(Depth==4){for(i=0;ifor(j=0;jfor(k=0;kCalculate_24(Rank,FourNum,Oper,i,j,k,def);}else{for(i=0;i{int Remember=0;for(j=0;j{if(Rank[j]==i)Remember=1;}if(Remember)continue;Rank[Depth]=i;SearchTree(Depth+1,Rank,FourNum,Oper,def);}}}int main(){int a[4],b[4],time;char c[4]={'+','-','*','/'};bool def=false;cin>>time;while(time--){for(int i=0;icin>>a[i];coutSearchTree(0,b,a,c,def);if(def==false)cout}return 0;}
急求java编程24点游戏的源代码!!!!!!!!!!!!!!!!!...
function log(str) { document.write(""+str); }//生成计算表达式 function genExpress(exp,a,b,c,d,m1,m2,m3) { var exp=exp.replace("a",a); exp=exp.replace("b",b); exp=exp.replace("c",c); exp=exp.replace("d",d); exp=exp.replace("m1",m1); exp=exp.replace("m2",m2); exp=exp.replace("m3",m3); return exp; } var answer = new Array();//正确答案的表达式 var counter = 0;//答案的个数//测试表达式是否正确 function test(expn,a,b,c,d,m1,m2,m3) { var exp; var ret; exp = genExpress(expn,a,b,c,d,m1,m2,m3);//生成计算表达式 eval("ret = "+exp); if ( Math.abs(ret - 24) { exp = exp.replace(";",""); exp = replaceAll(exp,"*","*"); exp = replaceAll(exp, "/","÷"); var have = false; for ( var i=0; i { if ( exp == answer[i] ) { have = true; break; } } if ( !have ) { answer[counter] = exp; counter++; log(""+counter+": "+exp+""); } } } function replaceAll (streng, soeg, erstat) { var st = streng; if (soeg.length == 0) return st; var idx = st.indexOf(soeg); while (idx >= 0) { st = st.substring(0,idx) + erstat + st.substr(idx+soeg.length); idx = st.indexOf(soeg); } return st; } var n = new Array();//四个数字//接收四个输入框的数字,调用主程序 function funCount() { n[0] = document.forms[0].fa.value; n[1] = document.forms[0].fb.value; n[2] = document.forms[0].fc.value; n[3] = document.forms[0].fd.value; if ( n[0] > 0 && n[1] > 0 && n[2] > 0 && n[3] > 0 && n[0] { log(""+n[0]+", "+n[1]+", "+n[2]+", "+n[3]+"的24点答案:"); log(""); funMain(); if ( counter == 0 ) { log("没有答案!"); } } else { alert("输入错误!"); } }//主程序 function funMain() { var m = new Array(); //四种运算符 m[0] = "+"; m[1] = "-"; m[2] = "*"; m[3] = "/"; //11种表达式 var exp1 = "a m1 b m2 c m3 d;"; var exp2 = "(a m1 b) m2 c m3 d;"; var exp3 = "(a m1 b m2 c) m3 d;"; var exp4 = "((a m1 b) m2 c) m3 d;"; var exp5 = "(a m1 (b m2 c)) m3 d;"; var exp6 = "a m1 (b m2 c) m3 d;"; var exp7 = "a m1 (b m2 c m3 d);"; var exp8 = "a m1 ((b m2 c) m3 d);"; var exp9 = "a m1 (b m2 (c m3 d));"; var exp10 = "a m1 b m2(c m3 d);"; var exp11 = "(a m1 b) m2 (c m3 d);"; var a,b,c,d;//四个数字 var m1,m2,m3;//三个运算符 for (var i=0;i { a = n[i]; for (var j=0;j { if ( i == j ) continue;//从未选的三个数字中选择一个数字 b = n[j]; for (var x=0;x { if ( x == j || x == i ) continue;//从未选的两个数字中选择一个数字 c = n[x]; for (var y=0;y { if ( y == x || y == j || y == i ) continue;//从未选的一个数字中选择一个数字 d = n[y]; for (var ta=0;ta { m1 = m[ta]; for (var tb=0;tb { m2 = m[tb]; for (var tc=0;tc { m3 = m[tc]; for (var k=1;k { eval("test(exp"+k+",a,b,c,d,m1,m2,m3);"); } } } } } } } } }
如何查看一个软件的程序?各位老师:用什么工具可以查看到一个软件...
用MFC开发24核心代码 void CMfcDlgAppDlg::OnAdd() { // TODO: Add your control notification handler code here UpdateData(); //获取编辑框录入的数据 m_symbol="+"; m_equation="="; m_result=m_num1+m_num2; m_doing="Adding"; UpdateData(FALSE); //在编辑框中显示数据 } void CMfcDlgAppDlg::OnSub() { // TODO: Add your control notification handler code here UpdateData(); m_symbol="-"; m_equation="="; m_result=m_num1-m_num2; m_doing="subtract"; UpdateData(FALSE); } void CMfcDlgAppDlg::OnMul() { // TODO: Add your control notification handler code here UpdateData(); m_symbol="*"; m_equation="="; m_result=m_num1*m_num2; m_doing="multiply"; UpdateData(FALSE); } void CMfcDlgAppDlg::OnDiv() { // TODO: Add your control notification handler code here UpdateData(); m_symbol="÷"; m_equation="="; if(m_num2) m_result=m_num1/m_num2; else AfxMessageBox("除数不能为0!"); m_doing="divide"; UpdateData(FALSE); } void CMfcDlgAppDlg::OnAbout() { // TODO: Add your control notification handler code here AfxMessageBox("程序设计:钟伟 地址:228寝室"); }
如何破解软件有没有可以用来破解软件的程序?
十招教你学会软件破解 下面谈到了一些在学习解密过程中经常遇到的问题,本人根据自己的经验简单给大家谈一谈。
这些问题对于初学者来说常常是很需要搞明白的,根据我自己的学习经历,如果你直接照着很多破解教程去学习的话,多半都会把自己搞得满头的雾水,因为有很多的概念要么自己不是很清楚,要么根本就不知道是怎么一回事,所以希望通过下面的讨论给大家一定的帮助: 1. 断点:所谓断点就是程序被中断的地方,这个词对于解密者来说是再熟悉不过了。
那么什么又是中断呢?中断就是由于有特殊事件(中断事件)发生,计算机暂停当前的任务(即程序),转而去执行另外的任务(中断服务程序),然后再返回原先的任务继续执行。
打个比方:你正在上班,突然有同学打电话告诉你他从外地坐火车过来,要你去火车站接他。
然后你就向老板临时请假,赶往火车站去接同学,接着将他安顿好,随后你又返回公司继续上班,这就是一个中断过程。
我们解密的过程就是等到程序去获取我们输入的注册码并准备和正确的注册码相比较的时候将它中断下来,然后我们通过分析程序,找到正确的注册码。
所以我们需要为被解密的程序设置断点,在适当的时候切入程序内部,追踪到程序的注册码,从而达到crack的目的。
2. 领空:这是个非常重要的概念,但是也初学者是常常不明白的地方。
我们在各种各样的破解文章里都能看到领空这个词,如果你搞不清楚到底程序的领空在哪里,那么你就不可能进入破解的大门。
或许你也曾破解过某些软件,但那只是瞎猫碰到死老鼠而已(以前我就是这样的^_^,现在说起来都不好意思喔!)。
所谓程序的领空,说白了就是程序自己的地方,也就是我们要破解的程序自己程序码所处的位置。
也许你马上会问:我是在程序运行的时候设置的断点,为什么中断后不是在程序自己的空间呢?因为每个程序的编写都没有固定的模式,所以我们要在想要切入程序的时候中断程序,就必须不依赖具体的程序设置断点,也就是我们设置的断点应该是每个程序都会用到的东西。
在DOS时代,基本上所有的程序都是工作在中断程序之上的,即几乎所有的DOS程序都会去调用各种中断来完成任务。
但是到了WINDOWS时代,程序没有权力直接调用中断,WINDOWS系统提供了一个系统功能调用平台(API),就向DOS程序以中断程序为基础一样,WINDOWS程序以API为基础来实现和系统打交道,从而各种功能,所以WINDWOS下的软件破解其断点设置是以API函数为基础的,即当程序调用某个API函数时中断其正常运行,然后进行解密。
例如在SOFTICE中设置下面的断点:bpx GetDlgItemText(获取对话框文本),当我们要破解的程序要读取输入的数据而调用GetDlgItemText时,立即被SOFTICE拦截到,从而被破解的程序停留在GetDlgItemText的程序区,而GetDlgItemText是处于WINDWOS自己管理的系统区域,如果我们擅自改掉这部分的程序代码,那就大祸临头了^_^!所以我们要从系统区域返回到被破解程序自己的地方(即程序的领空),才能对程序进行破解,至于怎样看程序的领空请看前面的SOFTICE图解。
试想一下:对于每个程序都会调用的程序段,我们可能从那里找到什么有用的东西吗?(怎么样去加密是程序自己决定的,而不是调用系统功能实现的!) 3. API:即Application Programming Interface的简写,中文叫应用程序编程接口,是一个系统定义函数的大集合,它提供了访问操作系统特征的方法。
API包含了几百个应用程序调用的函数,这些函数执行所有必须的与操作系统相关的操作,如内存分配、向屏幕输出和创建窗口等,用户的程序通过调用API接口同WINDOWS打交道,无论什么样的应用程序,其底层最终都是通过调用各种API函数来实现各种功能的。
通常API有两中基本形式:Win16和Win32。
Win16是原来的、API的16位版本,用于Windows 3.1;Win32是现在的、API的32位版本,用于Windows 95/98/NT/ME/2000。
Win32包括了Win16,是Win16的超集,大多数函数的名字、用法都是相同的。
16位的API函数和32位的API函数的区别在于最后的一个字母,例如我们设置这样的断点:bpx GetDlgItemText、bpx GetDlgItemTextA和bpx GetDlgItemTextW,其中 GetDlgItemText是16位API函数,GetDlgItemTextA和GetDlgItemTextW是32位API函数,而GetDlgItemTextA表示函数使用单字节,GetDlgItemTextW表示函数使用双字节。
现在我们破解中常用到的是Win32单字节API函数,就是和GetDlgItemTextA类似的函数,其它的两种(Win16 API和Win32双字节API函数)则比较少见。
Win32 API函数包含在动态链接库(Dynamic Link Libraries,简称DLLs)中,即包含在kernel32.dll、user32.dll、gdi32.dll和comctl32.dll中,这就是为什么我们要在softice中用exp=C:windowssystemkernel32.dll等命令行将这些动态链接库导入softice中的原因。
因为不这样做的话,我们就无法拦截到系统Win32 API函数调用了。
4. 关于程序中注册码的存在方式:破解过程中我们都会去找程序中将输入的注册码和正确的注册码相比较的地方,然后通过对程序的跟踪、...
如何自己编程序做软件?
首先。
。
。
先别想着用什么技术、什么工具。
你要确定你要开发的软件用来处理什么业务的。
然后你就从软件工程的角度出发,做可行性研究报告、需求分析、概要设计、详细设计、数据库设计、Coding、测试文档的编写(包括单元测试和集成测试)、编写用户手册(也就是所谓的帮助文档)。
为什么做个软件要这么复杂呢。
我认为要做的话就做得有意义点,不要自己天天在写程序,做出来的东西是不是真的有作用,有意义。
以此也能锻炼你的软件设计水平和编程水平。
等你的各项需求完善了,开始编写代码的时候,需要先把整个系统的架构进行设计分析,这方面包括的东西很广,自己有空可以慢慢了解;主要是技术的选型,根据你的业务处理的要求选择你要使用的技术,至于说用什么开发工具,因人而定。
喜欢哪个就用哪个。
...