24点(目前最新版本为O3)

O3

点击关闭/展开
#include<bits/stdc++.h>
#include<windows.h>
#define ll long long
using namespace std;
const int MAXN=1e6+5;

char s[MAXN];
int nums[4],used[4];
ll rete,t; 
vector<int> target;

// 检查是否包含4个指定数字
bool checkNums(){
    int cnt[10]={0};
    for(int i=0;s[i];i++){
        if(isdigit(s[i])){
            int num=s[i]-'0';
            if(num>=1&&num<=9) cnt[num]++;
        }
    }

    // 复制nums到临时数组
    int temp[4];
    for(int i=0;i<4;i++) temp[i]=nums[i];

    // 检查每个数字是否都出现且只出现一次
    for(int i=0;i<4;i++){
        bool found=false;
        for(int j=0;j<4;j++){
            if(temp[j]==nums[i]&&cnt[nums[i]]>0){
                cnt[nums[i]]--;
                temp[j]=-1; // 标记已使用
                found=true;
                break;
            }
        }
        if(!found) return false;
    }

    // 检查是否有多余数字
    for(int i=1;i<=9;i++){
        if(cnt[i]>0) return false;
    }
    return true;
}

// 计算中缀表达式
int calc(){
    stack<int> num;
    stack<char> op;
    auto eval=[&](){
        int b=num.top(); num.pop();
        int a=num.top(); num.pop();
        char c=op.top(); op.pop();
        if(c=='+') num.push(a+b);
        else if(c=='-') num.push(a-b);
        else if(c=='*') num.push(a*b);
        else if(c=='/') {
            if(b==0) return false;
            num.push(a/b);
        }
        return true;
    };

    unordered_map<char,int> pri{{'+',1},{'-',1},{'*',2},{'/',2}};

    for(int i=0;s[i];i++){
        if(s[i]==' ') continue;
        if(isdigit(s[i])){
            int x=0;
            while(isdigit(s[i])) x=x*10+s[i++]-'0';
            i--;
            num.push(x);
        }else if(s[i]=='('){
            op.push(s[i]);
        }else if(s[i]==')'){
            while(!op.empty()&&op.top()!='('){
                if(!eval()) return -1;
            }
            if(op.empty()) return -1;
            op.pop();
        }else{
            while(!op.empty()&&op.top()!='('&&pri[op.top()]>=pri[s[i]]){
                if(!eval()) return -1;
            }
            op.push(s[i]);
        }
    }
    while(!op.empty()){
        if(!eval()) return -1;
    }
    if(num.size()!=1) return -1;
    return num.top();
}

int main(){
	while(1){
		system("cls");
    	srand(time(0));
    	printf("Do you want to play again (If you first play,please ignore and reply : Yes .)?\nYes or No ?\n");
    	string ans;
    	cin>>ans;
    	if(ans=="No"){
    		printf("Good bye ~ I hope I will see you soon!\n");
    		Sleep(1000);
    		break;
		}
    	printf("Please wait for a moment ...\n");
    	for(int i=0;i<4;i++){
    	    nums[i]=rand()%9+1; // 1-9之间的数字
    	    Sleep(500); 
		}
    	printf("OK!\n");
    	Sleep(100); 
    	system("cls");
    	t=time(0);
    	while(1){
	        rete++;
    		printf("生成的4个数字: ");
    	    for(int i=0;i<4;i++) printf("%d ",nums[i]);
    		printf("\n");
    		printf("请输入中缀表达式(输入字符'/'退出): ");
    		cin.getline(s,MAXN);
    		// 检查数字
    		if(s[0]=='/') return 0; 
    		if(!checkNums()){
			printf("错误: 表达式必须包含且仅包含指定的4个数字\n");
			Sleep(1000);
        	t+=1;
			system("cls");
			continue;
    	}
    	// 计算表达式
    	int res=calc();
    	if(res==-1){
			printf("错误: 表达式计算失败\n");
			Sleep(1000);
			t+=1;
			system("cls");
			continue;
		}	
    	printf("计算结果: %d\n",res);
		if(res==24){
			printf("恭喜! 计算结果为24\n");
			printf("共使用%lld次!用时%lld秒!",rete,time(0)-t);
			Sleep(1000);
			t+=1;
			break; 
		}
		else printf("遗憾! 结果不是24\n");
			Sleep(1000);
			t+=1;
			system("cls");
		}
	}

    return 0;
}

O2

点击关闭/展开
#include<bits/stdc++.h>
#include<windows.h>
#define ll long long
using namespace std;
const int MAXN=1e6+5;

char s[MAXN];
int nums[4],used[4];
ll rete,t; 
vector<int> target;

// 检查是否包含4个指定数字
bool checkNums(){
    int cnt[10]={0};
    for(int i=0;s[i];i++){
        if(isdigit(s[i])){
            int num=s[i]-'0';
            if(num>=1&&num<=9) cnt[num]++;
        }
    }

    // 复制nums到临时数组
    int temp[4];
    for(int i=0;i<4;i++) temp[i]=nums[i];

    // 检查每个数字是否都出现且只出现一次
    for(int i=0;i<4;i++){
        bool found=false;
        for(int j=0;j<4;j++){
            if(temp[j]==nums[i]&&cnt[nums[i]]>0){
                cnt[nums[i]]--;
                temp[j]=-1; // 标记已使用
                found=true;
                break;
            }
        }
        if(!found) return false;
    }

    // 检查是否有多余数字
    for(int i=1;i<=9;i++){
        if(cnt[i]>0) return false;
    }
    return true;
}

// 计算中缀表达式
int calc(){
    stack<int> num;
    stack<char> op;
    auto eval=[&](){
        int b=num.top(); num.pop();
        int a=num.top(); num.pop();
        char c=op.top(); op.pop();
        if(c=='+') num.push(a+b);
        else if(c=='-') num.push(a-b);
        else if(c=='*') num.push(a*b);
        else if(c=='/') {
            if(b==0) return false;
            num.push(a/b);
        }
        return true;
    };

    unordered_map<char,int> pri{{'+',1},{'-',1},{'*',2},{'/',2}};

    for(int i=0;s[i];i++){
        if(s[i]==' ') continue;
        if(isdigit(s[i])){
            int x=0;
            while(isdigit(s[i])) x=x*10+s[i++]-'0';
            i--;
            num.push(x);
        }else if(s[i]=='('){
            op.push(s[i]);
        }else if(s[i]==')'){
            while(!op.empty()&&op.top()!='('){
                if(!eval()) return -1;
            }
            if(op.empty()) return -1;
            op.pop();
        }else{
            while(!op.empty()&&op.top()!='('&&pri[op.top()]>=pri[s[i]]){
                if(!eval()) return -1;
            }
            op.push(s[i]);
        }
    }
    while(!op.empty()){
        if(!eval()) return -1;
    }
    if(num.size()!=1) return -1;
    return num.top();
}

int main(){
    srand(time(0));
    printf("Please wait for a moment ...\n");
    for(int i=0;i<4;i++){
        nums[i]=rand()%9+1; // 1-9之间的数字
        Sleep(500); 
	}
    printf("OK!\n");
    Sleep(500); 
    system("cls");
    t=time(0);
    while(1){
        rete++;
    	printf("生成的4个数字: ");
        for(int i=0;i<4;i++) printf("%d ",nums[i]);
    	printf("\n");
    	printf("请输入中缀表达式(输入字符'/'退出): ");
    	cin.getline(s,MAXN);
    	// 检查数字
    	if(s[0]=='/') return 0; 
    	if(!checkNums()){
        	printf("错误: 表达式必须包含且仅包含指定的4个数字\n");
        	Sleep(1000);
        	t+=1;
			system("cls");
			continue;
    	}
    	// 计算表达式
    	int res=calc();
    	if(res==-1){
			printf("错误: 表达式计算失败\n");
			Sleep(1000);
			t+=1;
			system("cls");
			continue;
		}	
    	printf("计算结果: %d\n",res);
		if(res==24){
			printf("恭喜! 计算结果为24\n");
			printf("共使用%lld次!用时%lld秒!",rete,time(0)-t);
			Sleep(1000);
			t+=1;
			break; 
		}
		else printf("遗憾! 结果不是24\n");
		Sleep(1000);
		t+=1;
		system("cls");
	}

    return 0;
}

O1

点击关闭/展开
#include <windows.h>
#include <time.h>
#define ll long long
#include<bits/stdc++.h>
using namespace std;
#define N 1005
struct Node
{
    int n;
    char c;
};
Node eq[N]; 
int p;
int pri[128];
string s;
void initPri()
{
    pri['('] = 4;
    pri['*'] = pri['/'] = 3;
    pri['+'] = pri['-'] = 2;
    pri[')'] = 1;
} 
int calc(int a, int b, char c) 
{
	switch(c)
	{
		case '+':
			return a+b;
		case '-':
			return a-b;
		case '*':
			return a*b;
		case '/':
			return a/b;
	}	
}
bool isCalc(char c)
{
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
} 
bool isValid()
{ 
    stack<char> stk;
    for(int i = 0; i < s.length(); ++i) 
    {
        if(s[i] == '(')
            stk.push(s[i]);
        else if(s[i] == ')')
        {
            if(stk.empty())
                return false;
            else
                stk.pop();
        }
    }
    if(stk.empty() == false)
        return false; 
    for(int i = 0; i < s.length(); ++i)
    {
        if(i == 0 && s[i] == '-')
            s = '0' + s;
        else if(s[i] == '-' && s[i-1] == '(')
            s.insert(i, "0"); 
    }
    if(isCalc(s[0]) && s[0] != '(')
        return false;
    int ed = s.length()-1; 
    if(isCalc(s[ed]) && s[ed] != ')')
        return false;
    for(int i = 0; i < s.length()-1; ++i)
    {
        if(isCalc(s[i]) && isCalc(s[i+1]))
        {
            if(s[i] == ')' && s[i+1] == '(')
                return false;
            else if(!(s[i] == ')' || s[i+1] == '('))
                return false;
        }       
    } 
    return true;
}
int solve() 
{
    int i = p--;
    if(eq[i].c)
    {
        int b = solve(); 
        int a = solve();
        return calc(a, b, eq[i].c);
    }
    else
        return eq[i].n;
}
int main()
{
	int a1,a2,a3,a4;
	srand(time(0));
	a1=rand()%13+1, a2=rand()%13+1, a3=rand()%13+1, a4=rand()%13+1;
	cout<<a1<<endl<<a2<<endl<<a3<<endl<<a4<<endl; 
    initPri();
	int n, num = 0;
	cin >> s;
	if(isValid() == false)
	{
	    cout << "NO";
	    return 0;
    }
	s += ')'; 
	stack<char> cStk;
	bool isFormingNum = false;
	for(int i = 0; i < s.length(); ++i)
	{
		if(s[i] >= '0' && s[i] <= '9')
		{
			isFormingNum = true;
			num = num * 10 + s[i] - '0';
		}
		else
		{
			if(isFormingNum) 
			{
			    eq[++p].n = num;
				num = 0;
				isFormingNum = false;
			}
			while(!(cStk.empty() || pri[s[i]] > pri[cStk.top()] || cStk.top() == '('))
{
			    eq[++p].c = cStk.top(); 
                cStk.pop();
			}
			if(cStk.empty() == false && cStk.top() == '(' && s[i] == ')')
				cStk.pop();
			else 
				cStk.push(s[i]);
		}
	}
	cout << (solve()==24 ? "That is OK ." : "Error.");//to_string(solve())
	return 0;
}