Game 24点游戏算法
问题:给4个1-10的数字,通过加减乘除,得到数字为24就算胜利。输入:4个1-10的数字;输出:True or False;
方法一 暴力搜索
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
using namespace std;
void cal(double re[6], double a, double b) {
re[0] = a + b;
re[1] = a - b;
re[2] = b - a;
re[3] = a * b;
re[4] = a * 1.0 / b;
re[5] = b * 1.0 / a;
}
bool is24Points(double a, double b) {
double re[6];
cal(re, a, b);
int i;
for (i = 0; i < 6; ++i) {
if (re[i] == 24) {
return true;
}
}
return false;
}
void calThree(double re[108], double a, double b, double c) {
int i, j, k;
k = 0;
double fi[6];
double tt[6];
cal(fi, a, b);
for (i = 0; i < 6; ++i) {
cal(tt, fi[i], c);
for (j = 0; j < 6; ++j) {
re[k++] = tt[j];
}
}
cal(fi, a, c);
for (i = 0; i < 6; ++i) {
cal(tt, fi[i], b);
for (j = 0; j < 6; ++j) {
re[k++] = tt[j];
}
}
cal(fi, b, c);
for (i = 0; i < 6; ++i) {
cal(tt, fi[i], a);
for (j = 0; j < 6; ++j) {
re[k++] = tt[j];
}
}
}
bool Game24Points(int a, int b, int c, int d) {
double re[108];
int i;
calThree(re, b, c, d);
for (i = 0; i < 108; i++) {
if (is24Points(re[i], a))
return true;
}
calThree(re, a, c, d);
for (i = 0; i < 108; i++) {
if (is24Points(re[i], b))
return true;
}
calThree(re, a, b, d);
for (i = 0; i < 108; i++) {
if (is24Points(re[i], c))
return true;
}
calThree(re, a, b, c);
for (i = 0; i < 108; i++) {
if (is24Points(re[i], d))
return true;
}
return false;
}
int main() {
cout << Game24Points(1, 2, 3, 4) << endl;
cout << Game24Points(7, 2, 1, 10) << endl;
cout << Game24Points(7, 7, 7, 7) << endl;
return 0;
}
方法二 递归回溯
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <math.h>
const double EPS = 1e-6;
double s[4] = { 0, 0, 0, 0 };
bool process(int n) {
if (n == 1) {
if (fabs(24 - s[0]) < EPS)
return true;
else
return false;
}
double a, b;
int i, j;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++) {
a = s[i];
b = s[j];
s[j] = s[n - 1];
s[i] = a + b;
if (process(n - 1))
return true;
s[i] = a - b;
if (process(n - 1))
return true;
s[i] = b - a;
if (process(n - 1))
return true;
s[i] = a * b;
if (process(n - 1))
return true;
if (b != 0) {
s[i] = a / b;
if (process(n - 1))
return true;
}
if (a != 0) {
s[i] = b / a;
if (process(n - 1))
return true;
}
s[i] = a;
s[j] = b;
}
return false;
}
bool Game24Points(int a, int b, int c, int d) {
s[0] = a;
s[1] = b;
s[2] = c;
s[3] = d;
if (process(4))
return true;
else
return false;
}
int main() {
std::cout << Game24Points(1, 2, 3, 4) << "\n";
std::cout << Game24Points(0, 0, 0, 1) << "\n";
return 0;
}
周期串问题
问题:一个字符串可以由某个长度为k的字符串重复多次得到,称该串以k为周期。编写程序求周期,例如,abcabcabcabc以3为周期。
#include <iostream>
int GetMinPeriod(char *inputstring) {
int i, j;
int len = strlen(inputstring);
int result = len;
for (i = 1; i < len / 2 + 1; i++) {
for (j = 0; j < len - i; j++) {
if (inputstring[j] != inputstring[j + i])
break;
}
if (j == len - i) {
result = i;
break;
}
}
return result;
}
int main(){
char* p = "abcabcabcabc";
std::cout << GetMinPeriod(p); //3
return 0;
}
删除重复字符
问题:给定一个字符串,将字符串中所有和前面重复多余的字符删除,其余字符保留,输出处理后的字符串。需保证字符顺序,并区分大小写。
#include <map>
#include <iostream>
int GetResult(const char *input, char *output)
{
if (input == NULL || output == NULL)
return -1;
std::map<char, int> m;
const char *p = input;
while (*p) m[*p++] = 0;
p = input;
while (*p) {
++m[*p];
if (m[*p] == 1) *output++ = *p;
++p;
}
*output = '\0';
return 0;
}
int main()
{
char *p = "aabbcdae";
char *ou = (char *) malloc(1000);
GetResult(p, ou);
std::cout << ou ;
}
N皇后
问题:国际象棋中任意两个皇后都不能处于同一行、同一列或同一斜线上。把N个皇后放在棋盘(N×N) 上,求放置N 皇后方案的个数。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
static int g_table[20] = {0};
bool find(int row, int col)
{
for (int i = 1; i < row; ++i) {
if (g_table[i] == col || abs(i - row) == abs(g_table[i] - col))
return false;
}
return true;
}
void place(int row, int n, int *count)
{
if (row > n) {
++*count;
return;
}
for (int col = 1; col <= n; col++) {
if (find(row, col)) {
g_table[row] = col;
place(row + 1, n, count);
}
}
}
int PlaceQueenMethodNum(int n)
{
int count = 0;
place(1, n, &count);
return count;
}
int main()
{
std::cout << PlaceQueenMethodNum(8) << "\n"; // 92
std::cout << PlaceQueenMethodNum(12) << "\n"; // 14200
}
大数阶乘
问题:请设计一个程序,使其可以计算100以内的数的阶乘,结果用字符串的形式输出。
#include <iostream>
using namespace std;
void CalcNN(int n, char *pOut) {
int a[5000];
memset(a, 0, sizeof(a));
a[0] = 1;
int i, j, k, len = 0;
for (i = 1; i <= n; ++i) {
for (j = 0; j <= len; ++j)
a[j] *= i;
for (j = 0; j <= len; ++j) {
if (a[j] < 10)
continue;
k = j;
while (k <= len) {
if (a[len] > 9)
++len;
a[k + 1] += a[k] / 10;
a[k] %= 10;
++k;
}
}
}
char *p = pOut;
for (i = len; i >= 0; --i) {
*p++ = '0' + a[i];
}
*p = '\0';
return;
}
int main() {
char *p = (char *) malloc(1000);
CalcNN(13, p);
cout << p;
}
对象管理器
问题:实现一个对象管理器,可以插入,查找,删除。插入要求首先判断是否已经有相同对象存在,删除操作可以通过通配符进行批量删除;
#include <set>
#include <vector>
using std::set;
using std::vector;
class Myobj {
public:
Myobj():key1(0),key2(0),key3(0) {}
Myobj(unsigned int key1,unsigned int key2,unsigned int key3):
key1(key1),key2(key2),key3(key3) {}
bool operator < (const Myobj& a) const{
if(key1 < a.key1)
return true;
if(key1 == a.key1 && key2 < a.key2)
return true;
if(key1 == a.key1 && key2 == a.key2 && key3 < a.key3)
return true;
return false;
}
bool operator == (const Myobj& a) const{
if(key1 == a.key1 && key2 == a.key2 && key3 == a.key3){
return true;
} else {
return false;
}
}
public:
unsigned int key1;
unsigned int key2;
unsigned int key3;
};
static set<Myobj> g_myobj;
int AddObject (unsigned int key1, unsigned int key2, unsigned int key3) {
Myobj o(key1,key2,key3);
if(g_myobj.insert(o).second)
return 0;
else
return -1;
}
void DeleteObject (unsigned int key1, unsigned int key2, unsigned int key3) {
set<Myobj>::iterator it;
vector< set<Myobj>::iterator > ve;
for(it = g_myobj.begin(); it != g_myobj.end(); ++it){
if( (key1 == 0xFFFFFFFF || key1 == it->key1) &&
(key2 == 0xFFFFFFFF || key2 == it->key2) &&
(key3 == 0xFFFFFFFF || key3 == it->key3) )
ve.push_back(it);
}
for(int i = 0; i < ve.size(); ++i){
g_myobj.erase(ve[i]);
}
return ;
}
int IsObjectExist (unsigned int key1, unsigned int key2, unsigned int key3) {
Myobj o(key1,key2,key3);
if(g_myobj.count(o))
return 1;
else
return 0;
}
void Clear(void) {
g_myobj.clear();
return;
}
删除链表重复节点剩余逆序输出
问题:删除单链表中重复的节点,删除重复不是保留一个,而是都删除,剩余节点逆序输出,输出节点除了首节点外其它需自己重新开辟内存。
#include <stdlib.h>
#include <map>
#include <vector>
#include <algorithm>
#include "oj.h"
using std::map;
using std::vector;
using std::reverse;
int iChanProcess(strNode * pstrIn, strNode * pstrOut) {
if (pstrIn == NULL || pstrOut == NULL)
return 0;
map<int, int> m;
strNode *p = pstrIn, *temp = NULL;
while (p != NULL) {
m[p->data] = 0;
p = p->pstrNext;
}
p = pstrIn;
while (p != NULL) {
m[p->data]++;
p = p->pstrNext;
}
p = pstrIn;
vector<strNode*> ve;
while (p != NULL) {
if (m[p->data] == 1) {
temp = (strNode *) malloc(sizeof(strNode));
temp->data = p->data;
temp->pstrNext = NULL;
ve.push_back(temp);
}
p = p->pstrNext;
}
reverse(ve.begin(), ve.end());
for (unsigned int i = 0; i < ve.size() - 1; ++i) {
ve[i]->pstrNext = ve[i + 1];
}
ve[ve.size() - 1] = NULL;
pstrOut->data = ve[0]->data;
pstrOut->pstrNext = ve[0]->pstrNext;
free(ve[0]);
return 0;
}
void vFreeChan(strNode * pstrChan) {
strNode *p;
while (pstrChan != NULL) {
p = pstrChan;
pstrChan = pstrChan->pstrNext;
free(p);
}
return;
}