【思考题】抽签游戏

给定一个初始状态无序的字符串(长度小于15),A、B两人从此串中依次取出一个字符,假设两人都足够理性,若取完后字符串严格递增有序(a[0]<a[1]<a[2]<...<a[n-1]),则此人获胜。
假设A先取,试判定A最终是胜还是负。
如:213,则A胜
222,则A败
2213,则A胜

假设AB都足够聪明,并都以获胜为目标。

思路:

1.在其中一个人获胜时,我们则要修改上一次另一个人的选择;

2.当某一个人穷尽所有想法都无法获胜,则他需要返回到他上一次的选择,采用另一种结果。

原理也就这么简单。

对于c++和java来说,可以使用map或者hash表记录出现的可能字符串,继而记录该字符串是否可以获胜,后面抽签所获得的字符串就可以引用之前的测试结果,从而加快效率。然后由递归,计算各种字符串组合是否可以满足严格递增有序,然后就可以判断A逐个抽出是否可以获胜了。

这里的record记录的是取出一个数字后剩余序列是否可以获胜。

#include <iostream>
#include <string>
#include <map>

using namespace std;

map<string, int> record;

int dp(string str){
	if (record.find(str) != record.end())
	{
		return record[str];
	}
	int i;
	for (i =1; i < str.size(); i++)
	{
		if (str[i-1] >= str[i])
		{
			break;
		}
	}
	if (i == str.size())
	{
		record[str] = 0;
		return 0;
	}

	for ( i= 0; i < str.size(); i++)
	{
		if (dp(str.substr(0,i) + str.substr(i+1)) == 0)    		{
			break;
		}
	}
	record[str] = (i != str.size());  //1:可以获胜
	return record[str];
}

int main(){
	string str;
	cin >> str;
	cout << dp(str) << endl;
	system("pause");
	return 0;
}


那么,c则没这些辅助,就得靠自己了。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int level=0;
int pd(int who, int* data, int n){  //返回向上层数
	int k, kk;
	int *newdata;
	int curwhook;

	for(k=0; k<n; k++){
		newdata = (int*)malloc(sizeof(int)*(n-1));
		if(k==0)
			memcpy(newdata, data+1, sizeof(int)*(n-1));
		else if(k==n-1)
			memcpy(newdata, data, sizeof(int)*(n-1));
		else{
			memcpy(newdata, data, sizeof(int)*k);
			memcpy(newdata+k, data+k+1, sizeof(int)*(n-k-1));
		}

		for(kk=1; kk<n-1; kk++){  //判断剩余序列是否严格递增
			if(*(newdata+kk)<=*(newdata+kk-1))
				break;
		}

		if(kk==n-1){  //序列严格递增
			//free(data);   //-----------
			free(newdata);  //-----------
			if(level==0){   //第0层,则可以确定必赢
				printf("A win
");
				system("pause");
				exit(0);
			}
			else{  //非第0层,返回上一层,让另一个人重新选
				level--;
				return 1;  //返回上一个用户
			}
		}
		else{  //并无严格递增
			level++;
			if(who==0){  //这次是A取的,下一次要B取
				if(pd(1, newdata, n-1)==1){
					free(newdata);  //----------
					continue;
				}
				else{  //-1
					//free(data);   //-----------
					free(newdata);  //-----------
					level--;  //------------
					return 1;
				}
			}
			else{
				if(pd(0, newdata, n-1)==1){
					free(newdata);  //-----------
					continue;
				}
				else{  //-1
					//free(data);   //-----------
					free(newdata);  //-----------
					level--;        //-------------
					return 1;
				}
			}
		}
	}

	if(k==n){  //穷尽了但找不到,返回同一个用户继续下一次循环
		if(level==0)
			printf("B win
");
		else{
			//free(data);  //-----------
			//free(newdata);  //-----------
			level--;
			if(level==0){
				printf("A win
");
				system("pause");
				exit(0);
			}
			return -1;
		}
	}
}

int main(void){
	char s[20];
	int slen, k, kk;
	int *data;
	int budayucnt;

	if(gets(s)==NULL)
		return 0;
	slen = strlen(s);
	data = (int*)malloc(sizeof(int)*slen);

	for(k=0; k<slen; k++){
		*(data+k) = s[k]-'0';
	}

	pd(0, data, slen);

	system("pause");
	return 0;
}


 

原文地址:https://www.cnblogs.com/xhyzjiji/p/6159376.html