华为机试OJ2

*/
功能: 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。如果有多对数字的和等于输入的数字,输出任意一对即可
输入: int aData[] // 升序数组
unsigned int uiLength // 数组元素个数
int sum, // 给定两个数组的和
输出: int *pNum1 // 第一个数字,对应数组索引小的
int *pNum2 // 第二个数字,对应数组索引大的
返回: 找到返回true,异常返回false
/*

#include "OJ.h"
#include <stdio.h>

bool FindTwoNumbersWithSum(int aData[], unsigned int uiLength, int sum, int *pNum1, int *pNum2)
{
    /*在这里实现功能*/
if(aData==NULL || uiLength<=0 || pNum1==NULL ||pNum2==NULL)     return false;
    for(int i=0; i<uiLength-1; i++){
        for(int j=1; j<uiLength; j++){
            if(aData[i]+aData[j] == sum){
                *pNum1=aData[i];
                *pNum2=aData[j];
                return true;
            }
        }
    }
    return false;
}

计算100以内任意数的阶乘
算法思想非常类似我们书面的乘法计算方法。程序中需要处理好每次的进位信息。
这里写图片描述

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "oj.h"
void calNN(int n,int *Out);

int tempOut[600]={0};
void CalcNN(int n, char *pOut)
{
    //memset(tempOut,0,600);

    calNN(n,tempOut);

    int j=0;
    int i=599;
    while(tempOut[i]==0) i--;

    for(; i>=0;i--){
        pOut[j++]=(char)(tempOut[i] + '0');
    }
    pOut[j]='\0';
    //free(tempOut);
    return;
}

void calNN(int n,int *Out){
    int i,m,c;
    static int Length=0;
    if(n==1){
        Out[0]=1;
        Length=0;
        return;
    }
    if(n>=2){
        calNN(n-1,Out);
        for(i=0,c=0; i<=Length; i++){
            m=Out[i]*n;
            Out[i]=(m+c)%10;
            c=(m+c)/10;
        }
        while(c){
            Out[i]=c%10;
            i++;
            Length++;
            c /= 10;
        }
    }
}

int main(){

    char test[600];
   CalcNN(100, test);

   for(int i=0; i<600; i++) printf("%c",test[i]);

   system("pause");
   return 0;
}

N皇后
皇后是国际象棋中威力最大的棋子。在下面所示的棋盘上,皇后可以攻击位于箭头所覆盖位置的所有棋子。我们能不能把N个皇后放在棋盘(N×N)上,它们中的任何一个都无法攻击其余的皇后?请编写程序找出一共有几种方法。

详细描述:

接口说明
原型:
intPlaceQueenMethodNum(int n);
输入参数:
int n: 皇后的个数

返回值:
int: 放置n皇后方案的个数


#include "OJ.h"
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;

bool find(int row, int col, int *count);
void place(int row, int n, int *q, int *count);

int PlaceQueenMethodNum(int n)
{
    /*在这里实现功能*/
    int count=0;
    int q[20];
    place(1,n, q, &count);

    return count;
}


void place(int row, int n, int *q, int *count)
{
    if(row>n){
        (*count)++;
        return;
    }
    int col=0;
    for(col=1; col<= n; col++){
        if(find(row,col,q)){
            q[row]=col;
            place(row+1, n, q, count);
        }
    }
}

bool find(int row, int col, int *q)
{
    int i=1;
    while(i< row){
        if(q[i] == col || abs(i-row)==abs(q[i] - col))
            return false;
        i++;
    }
    return true;
}

**题目简述:

在迷宫中找出最长环路的长度,不是找到出路。

详细描述:

迷宫是由一系列方格组成一个矩形区域,下图是一个 4 * 6 的迷宫
每个方格中都有一条红色的斜线(/或者\),这是墙,无法通过。灰线不是墙,可自由跨越。
在迷宫内,只能在相邻的(有公共边的才算相邻,公共顶点不算)三角形的区域之间相互移动。左上角灰色三角形,就是一个区域,从这个区域,可以移动到下面黄色三角形区域中。
不能越界,只能在大的矩形范围内移动。左边紫色这种移动方式,是不允许的。
可以看到,中间蓝色的分别是两条环路,环路长度指的是走完这条环路需要走过的三角区域个数,两条环路的长度分别是16和4;绿色的不是一条环路
这里写图片描述
这里写图片描述

**

#include "Maze.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

/* 功能:找出一个迷宫中的最长环路以及环路个数
 * 输入:存放迷宫信息的记事本文件路径,该程序从文件中读取迷宫信息。
 * 输出:CycleCount,环路个数
 * 返回:最长环路长度,如果没有环路,返回-1.
 */

struct Change {
    int x;
    int y;
};

Change CHANGE[] = {
    {-1, 0},
    { 0,-1},
    { 0, 1},
    { 1, 0},
};

const int LIMITS_W = 300;
const int LIMITS_H = 300;
int num_case = 0;
char maze[LIMITS_H][LIMITS_W];
int w=0, h=0;
int w_maze=0, h_maze=0;

void EnlargeAndSave(int x, int y, char ch);

int FloodFill(int x, int y);

int FindLongestCycle(const char* mazefile, int *CycleCount)
{
    w_maze=0;
    h_maze=0;
    w=0;
    h=0;
    memset(maze,0,LIMITS_W*LIMITS_H);

    if(mazefile==NULL || CycleCount==NULL)  return -1;
    FILE *fp;
    fp=fopen(mazefile,"r");
    char temp[50][50]={0};
    int i=0;
    while(fscanf(fp,"%s",temp[i++])!=EOF);

    for(int i=0;i<50; i++) if(*(temp[i])!=0) h++;

    for(int i=0;i<50; i++) if(temp[0][i]!=0) w++;

    for(int i=0; i<h;i++){
        for(int j=0; j<w; j++){
            EnlargeAndSave(i,j,temp[i][j]);
        }
    }
    w_maze = w*3;
    h_maze = h*3;

        // DFS: Remove grids of the maze without cycles.
        for (int i = 0; i < h_maze; ++i) {
            FloodFill(i, 0);
            FloodFill(i, w_maze - 1);
        }
        for (int i = 0; i < w_maze; ++i) {
            FloodFill(0, i);
            FloodFill(h_maze - 1, i);
        }
        // DFS: Search and compete the maze with cycles.
        int max = 0;
        int sum = 0;
        for (int i = 0; i < h_maze; ++i) {
            for (int j = 0; j < w_maze; ++j) {
                int result = FloodFill(i, j) / 3;
                if (result) {
                    max = result > max ? result : max;
                    ++sum;
                }
            }
        }
fclose(fp);

        if(sum) {
            *CycleCount=sum;
            return max;
        }else{
            return -1;  
        }

}

void EnlargeAndSave(int x, int y, char ch) {
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
            maze[x * 3 + i][y * 3 + j] = ' ';
        }
    }
    if (ch == '/') {
        maze[x * 3][y * 3 + 2] = '#';
        maze[x * 3 + 1][y * 3 + 1] = '#';
        maze[x * 3 + 2][y * 3] = '#';
    } else {
        maze[x * 3][y * 3] = '#';
        maze[x * 3 + 1][y * 3 + 1] = '#';
        maze[x * 3 + 2][y * 3 + 2] = '#';
    }
}

int FloodFill(int x, int y) {
    // Exit.
    if (x < 0 || x >= h_maze || y < 0 || y >= w_maze) {
        return 0;
    }
    if (maze[x][y] != ' ') {
        return 0;
    }
    // Continue.
    maze[x][y] = '#';
    int sum = 1;
    for (int i = 0; i < 4; ++i) {
        sum += FloodFill(x + CHANGE[i].x, y + CHANGE[i].y);
    }
    return sum;
}

中序表达式到 先序表达式转换,及求先序表达式的值

int toFrontexpression(string &expression){
    stack<char> s1;
    stack<char> s2;

    size_t len=expression.length();

    for(int i=len-1; i>=0; --i){

        if(expression[i]>'0'&&expression[i]<='9'+1) s2.push(expression[i]);  //如果遇到数字直接直接压入栈s2;
        else {
            switch(expression[i]){

                case ')':
                    s1.push(')');
                break;
                case '(':
                    while(s1.top()!=')'){
                        s2.push(s1.top());
                        s1.pop();
                    }
                    s1.pop();
                break;
                case 'x':
                case '/':
                    s1.push(expression[i]);
                break;
                case '-':
                case '+':

                    if(!s1.empty()){
                        while(!s1.empty()&&(s1.top()=='x'||s1.top()=='/')){    //确保栈不为空
                            s2.push(s1.top());
                            s1.pop();
                        }
                    }
                    s1.push(expression[i]);
                break;
                default :
                    return 1;
            }               
        }
    }
    while(!s1.empty()){
        s2.push(s1.top());
        s1.pop();
    }

    expression.clear();
    int j=0;
    while(!s2.empty()){
        expression += s2.top();
        s2.pop();
    }
    return 0;
}





float calFrontExp(string expression){
    int len=expression.length();
    stack<float> result;
    float temp=0,temp1=0,temp2=0;
    for(int i=len-1; i>=0; --i){
        if(expression[i]>='0'&&expression[i]<='9'+1){  //前项表达式自又向左扫描,遇到数字直接压站,
            result.push(expression[i]-'0');
        }else{   //遇到 运算符则取出栈顶的两个元素进行计算
            if(!result.empty()){
                temp1=result.top();
                result.pop();
            }
            if(!result.empty()){
                temp2=result.top();
                result.pop();
            }
            switch(expression[i]){
                case '+':
                    temp=temp1 + temp2;
                break;
                case '-':
                    temp=temp1 - temp2;
                break;      
                case 'x':
                    temp=temp1 * temp2;
                break;
                case '/':
                    temp=temp1 / temp2;
                break;
                default:
                    return 1;
            }
            result.push(temp);
        }   
    }
    return temp;
}

**背景:
编程实现如下功能:对输入的一元多项式,进行同类项合并,并按指数降序排序,输出处理后的一元多项式。

说明:
l 多项式由若干个单项式组成,单项式之间为加、减(+,-)关系。
l 单项式指数字与字母幂的乘积构成的代数式。对一元多项式,字母只有一种。
l 同类项合并指将多项式中指数相同的单项式,系数经过加减求和,合并为一个单项式。按指数降序指多项式中,单项式按指数从大到小顺序相连。

格式说明
一元多项式输入输出时以字符串形式表示,格式如下
l单项式之间用单个加减运算符相连,运算符:+,-
2单项式由系数、字母、指数标识符、指数依次直接相连组成,各部分均不能省略。
系数:只由若干0到9数字字符组成(系数不等于0,且不以0开头)
字母:X
指数标识符:^
指数:只由若干0到9数字字符组成(指数可等于0,不等于0时不以0开头)
3其他约定
输入不为空串,输出若为0则以空串表示
字符串中除以上字符,不包含空格等其他字符,字符串尾部以’\0’结束
多项式中第一个单项式前加运算时省略+符号,减运算时有-符号
注意:输入多项式符合上述格式,无需检查;输出多项式格式由考生程序保证
示例
例一
输入:
“7X^4-5X^6+3X^3”
输出:
“-5X^6+7X^4+3X^3”
例二
输入:
“-7X^4+5X^6-3X^3+3X^3+1X^0”
输出:
“5X^6-7X^4+1X^0”
**

/******************************************************************************

Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.

******************************************************************************
File Name     :
Version       :
Author        :
Created       : 2010/9
Last Modified :
Description   :
Function List :

History       :
1.Date        : 2010/9
Author      :
Modification: Created file

******************************************************************************/


/******************************************************************************************************
Description     : 对输入的一元多项式,进行同类项合并,输出处理后的一元多项式 
Prototype       : void OrderPolynomial (char* InputString, char* OutputString)
Input Param     : char* InputString 输入多项式字符串
Output Param    : char* OutputString 输出多项式字符串
Return Value    : void

********************************************************************************************************/
#include <iostream>
#include <map>
#include <string>
#include <stack>
using namespace std;

void OrderPolynomial (char* InputString, char* OutputString)
{
    /*在这里实现功能*/
    if(InputString==NULL)
        return;
    map<int,int> m;//输出要有序,所以采用map,key是指数,value是系数,带符号;
    int length = strlen(InputString);
    int i=0;
    while(i<length)
    {
        int coefficient = 0;
        int flag = false;
        if(InputString[i]=='-'||InputString[i]=='+')
        {
            if(InputString[i]=='-')
                flag = true;
            i++;
        }
        while(InputString[i]!='X')
        {
            coefficient =coefficient*10+ (InputString[i++]-'0');
        }
        if(flag)
            coefficient = -coefficient;
        i += 2;//跳过x^
        int index =0; 
        while(InputString[i]>='0'&&InputString[i]<='9')
        {
            index = index*10+(InputString[i++]-'0');
        }
        //if(m.find(index)!=m.end())//已经出现过相同的指数
        //  m.find(index)->second += coefficient;
        //else
        //  m.insert(pair<int,int>(index,coefficient));
        m[index] += coefficient;
    }
    map<int,int>::reverse_iterator rm = m.rbegin();
    char* begin = OutputString;
    for(;rm!=m.rend();rm++)
    {
        if(rm->second!=0)
        {
            if(rm->second<0)
            {
                *(begin++) = '-';
            }
            else 
                if(rm!=m.rbegin())
                {
                    *(begin++) = '+';
                }
            int temp = abs(rm->second);
            stack<char> s;
            while(temp!=0)
            {
                s.push(temp%10+'0');
                temp = temp/10;
            }
            while(!s.empty())
            {
                *(begin++) = s.top();
                s.pop();
            }
            *(begin++) = 'X';
            *(begin++) = '^';
             temp =  rm->first;
             if(temp==0)
                 *(begin++) ='0';
            while(temp!=0)
            {
                s.push(temp%10+'0');
                temp = temp/10;
            }
            while(!s.empty())
            {
                *(begin++) = s.top();
                s.pop();
            }
        }
    }
    *begin='\0';
    cout<<OutputString<<endl;
    return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值