华为机试OJ1

**题目描述
临近开学了,小C才想起来数学老师布置了暑假作业。暑假作业是很多张试卷,每张试卷所需的时间和获取的价值已知,请你帮他安排一下,用他仅剩的一点时间来做最有价值的作业。

接口说明
原型:
int GetMaxValue(int nPapers, int nRemain, int paper[][2], double* pMaxValue)
输入参数:
int nPapers:试卷的数目(1≤Papers≤20)
int nRemain:表示剩余的时间(1≤nRemain≤10000)
int paper[][2]:nPapers*2的数组,每一行的两个元素依次为做完这一份试卷所需的时间、做完这份试卷获取的价值。如果剩余时间不够做完一份卷子,可根据剩余时间获得卷子的部分价值。
输出参数:
double * pMaxValue:获得的最大价值
返回值:
0:异常,1:成功

题目理解:由于题目说试卷时间可分割,因此这就可以当成可划分的背包问题,可以利用贪心算法来解。
**

#include "OJ.h"
#include <algorithm> 
void bubbleSort(int paper[][2],int nPapers);
int GetMaxValue(int nPapers, int nRemain, int paper[][2], double* pMaxValue)
{
    if(nPapers<0||nRemain<0||paper==NULL||pMaxValue==NULL) return 0;
    bubbleSort(paper,nPapers);
    *pMaxValue=0;
    for(int i=0; i<nPapers; i++){
        if(nRemain>0){
            if(nRemain>=paper[i][0]){
                *pMaxValue += paper[i][1];
                nRemain -= paper[i][0];
            }else{
                *pMaxValue += (paper[i][1]*1.0 / paper[i][0]) * nRemain;
                nRemain=0;
            }
        }else break;
    }
    return 1;
}


//从大到小冒泡排序
void bubbleSort(int paper[][2],int nPapers){
    for(int i=0; i<nPapers; i++){
        for(int j=0; j<nPapers-i-1; j++){
            double db1,db2;
            int temp;
            db1= paper[j][1]*1.0/paper[j][0];
            db2= paper[j+1][1]*1.0/paper[j+1][0];
            if(db2 > db1){
                temp=paper[j][0];
                paper[j][0]=paper[j+1][0];
                paper[j+1][0]=temp;

                temp=paper[j][1];
                paper[j][1]=paper[j+1][1];
                paper[j+1][1]=temp;
            }
        }
    }
}

**题目描述
如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也可以6和12为周期,结果取最小周期3)。字符串的长度小于等于100,由调用者保证。
详细描述:
接口说明
原型:
int GetMinPeriod(char *inputstring);
输入参数:
char * inputstring:字符串
返回值:
int 字符串最小周期**
理解:利用周期性的特点,字符串左移或者右移n个周期,其对应位置的值不变。如
abcabcabc
abcabcabc右移三位

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

int GetMinPeriod(char *inputstring)
{

    if(inputstring ==NULL) return -1;
    int count=1;
    int len = strlen(inputstring);
    if(len==1) return 1;
    int j;
    for(count=1;count<=len/2+1; count++){
        for(j=count; j<len; j++){
            if(inputstring[j]!=inputstring[j-count]) break;
        }
        if(j==len) return count;
    }

    return len;
}

**密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有相同长度超2的子串重复
说明:长度超过2的子串**

样例输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

样例输出:
OK
NG
NG
OK

'注意:由于输入为多行,要使用getline读取输入数据否则极易出错'
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
int judgeCode(string &code);

int main(){
    string code;
    string temp;
    //vector<string> result;
    string s1;
    vector<string> s;
    while (getline(cin,s1))
    {
        if (judgeCode(s1)==0)
            //tmpstr="OK";
            cout<<"OK"<<endl;
        else
            cout<<"NG"<<endl;

    }
    return 0;
}

int judgeCode(string &code){

    int len=code.size();
    if(len<8) return 1;
    int characters[4]={0};  // A a 0 $
    for(int i=0; i<len; i++){
        if(code[i]<='Z'&&code[i]>='A') characters[0]=1;
        else if(code[i]<='z'&&code[i]>='a') characters[1]=1;
        else if(code[i]<='9'&&code[i]>='0') characters[2]=1;
        else characters[3]=1;
    }
    int sum=0;
    for(int i=0;i<4;i++) sum +=characters[i];

    if(sum<3) return 1;

    //查找重复子串
    vector<string> temp;
    //截取所有长度大于等于3的子串
    string sub_str;
    for(int subLen=3;subLen<=len; subLen++){
        for(int i=0;i<=len-subLen;i++){
            temp.push_back(code.substr(i,subLen));
        }
    }
    vector<string>::iterator tmp_iter;
    for(tmp_iter=temp.begin(); tmp_iter!=temp.end(); tmp_iter++){
        if(code.find(*tmp_iter)!=code.rfind(*tmp_iter)) return 1;
    }
    return 0;
}

有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出,问最后留下的那位是原来第几号。
下面是使用链表处理该问题的,其实该问题可以使用数组处理,方法会比较简单。

#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>

using namespace std;

typedef struct List{
    int num;
    struct List *next;
} List;

void generateList(List **head,int n){
    List *tail=NULL;
    *head=new List;
    (*head)->next=*head;
    (*head)->num=1;
    tail=*head;
    List *temp=NULL;

    for(int i=2; i<=n;i++){
        temp= new List;
        temp->next=*head;
        temp->num =i;
        tail->next = temp;
        tail =temp;
    }

}


int main(){
    int count=0;
    cin>>count;
    List *head=NULL;
    generateList(&head,count);
    List *index=head;
    List *temp=NULL;
    while(index->next!= index){
         index =index->next;
         temp=index->next->next;
         delete index->next;
         index->next = temp;
         index =index->next;
    }
    cout<<index->num<<endl;
    delete index;
    system("pause");
    return 0;
}

**
给定一个正整数N代表火车数量,N在0到10之间,不包括0和10,,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号。要求以字典序排序输出火车出站的序列号。
**
算法思想,首先计算出输入序列的全排列,然后利用栈的特点“任何在当前元素之后输出,且比该元素小的数,一定是逆序的

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int JudgeTrainSequence (string& str);

int main()
{
    int num;
    string str="ABCDEFGHIJ",a;

    vector<string> tmp;
    cin>>num; 
    getchar();
    getline(cin,a);
    str=str.substr(0,num);


    tmp.push_back(str);
    while(next_permutation(str.begin(),str.end())) 
        tmp.push_back(str);//得到了全排列
    vector<string>::iterator tmp_iter=tmp.begin();
    for (;tmp_iter!=tmp.end();)
    {
        string s=*tmp_iter;
        int len=s.size();
        string::iterator  s_iterator=s.begin()+1;
        while(s_iterator<s.end())
        {
            char ch=*(s.begin());
            if (*s_iterator>*(s.begin()))
            {
                s.erase(s_iterator);
            }else s_iterator++;
        }
        string q=s;
        sort(s.rbegin(),s.rend());  
        if(q!=s)  //判断是非满足出栈条件
            tmp_iter=tmp.erase(tmp_iter); 
        else tmp_iter++;
    }

    for(int j=0;j<tmp.size();j++)
        for (int i=0;i<num;i++)
            replace(tmp[j].begin(),tmp[j].end(),str[i],a[i*2]);
    sort(tmp.begin(),tmp.end());

    for (int i=0;i<tmp.size();i++)
    {
        string m;
        m=tmp[i];
        for (int k=0;k<m.size();k++)
        {
            cout<<m[k];
            if(k==m.size()-1)
                cout<<endl;
            else
                cout<<" ";
        }
    }
system("pause");
return 0;
}


int JudgeTrainSequence (string& str)  
{  
 int len=str.length();

 for(int i=0; i<len-1; i++){
    int max=str[i];
    int sw=0;
     for(int j=i+1; j<len; j++){
         if(str[j]<max){
             if(sw==0){
                max=str[j];
             }
             sw=1;
             if(str[j]>max) return 0;
         } 
     }
 }
    return 1;     
}

实现输入一组大于等于0的整数,根据从小到大的顺序排序后输出,排序后有连续数时,只输出连续数中最小和最大的两个数。

#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>

using namespace std;

int main(){
    int num[100]={0};
    string str;
    cin>>str;
    int temp=0;
    int j=0;
    for(int i=0; i< str.length(); i++){
        if(str[i]!=','){
            temp =temp*10 + (str[i]-'0');
        }else{
            num[j++]=temp;
            //cout<<num[j-1]<<' ';
            temp=0;
        }
    }
    num[j]=temp;

    sort(num,num+j+1);

    cout<<num[0]<<' ';
    int flag=0;
    for(int i=1; i<=j; i++){
        if(num[i]-num[i-1] == 1){
            //i++;
            flag=1;
        }
        else{
            if(flag==1){
                cout<<num[i-1]<<' '<<num[i]<<' ';
                flag=0;
            }
            else cout<<num[i]<<' ';
        }
    }
    if(flag==1) cout<<num[j];

    cout<<endl;
    system("pause");
    return 0;

}


**密码是我们生活中非常重要的东东,我们的那么一点不能说的秘密就全靠它了。哇哈哈. 接下来渊子要在密码之上再加一套密码,虽然简单但也安全。

假设渊子原来一个BBS上的密码为zvbo9441987,为了方便记忆,他通过一种算法把这个密码变换成YUANzhi1987,这个密码是他的名字和出生年份,怎么忘都忘不了,而且可以明目张胆地放在显眼的地方而不被别人知道真正的密码。

他是这么变换的,大家都知道手机上的字母: 1–1, abc–2, def–3, ghi–4, jkl–5, mno–6, pqrs–7, tuv–8 wxyz–9, 0–0,就这么简单,渊子把密码中出现的小写字母都变成对应的数字,数字和其他的符号都不做变换,

声明:密码中没有空格,而密码中出现的大写字母则变成小写之后往后移一位,如:X,先变成小写,再往后移一位,不就是y了嘛,简单吧。记住,z往后移是a哦。**

//简单密码破解
#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>

using namespace std;

int main(){
    string namestr;
    cin>>namestr;
    for(int i=0; i<namestr.length(); i++){
        switch(namestr[i]){
            case 'a':
            case 'b':
            case 'c':
                namestr[i]='2';
            break;
            case 'd':
            case 'e':
            case 'f':
                namestr[i]='3';
            break;
            case 'g':
            case 'h':
            case 'i':
                namestr[i]='4';
            break;
            case 'j':
            case 'k':
            case 'l':
                namestr[i]='5';
            break;
            case 'm':
            case 'n':
            case 'o':
                namestr[i]='6';
            break;
            case 'p':
            case 'q':
            case 'r':
            case 's':
                namestr[i]='7';
            break;
            case 't':
            case 'u':
            case 'v':
                namestr[i]='8';
            break;
            case 'w':
            case 'x':
            case 'y':
            case 'z':
                namestr[i]='9';
            break;
            default:
                if(namestr[i]<'Z'&&namestr[i]>='A'){
                    namestr[i] = namestr[i] + 'a'- 'A'+1;
                }
                else if(namestr[i]=='Z') namestr[i]='a';
            break;
        }
    }

    cout<<namestr<<endl;
    system("pause");
    return 0;
}

**计算整数的位数,并逆序输出
输入一个五位以内(包括5位)的正整数,(1)判断它是一个几位数;(2)逆序输出其各位数字。**
#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>
using namespace std;

int main(){
    int num=0;
    int count=0;
    int temp=0;
    cin>>num;
    temp=num;
    while(temp!=0){
        temp = temp/10;
        count++;
    }
    temp=num;
    cout<<count<<' ';
    while(temp!=0){
        cout<<temp%10;
        temp /=10;
    }
    cout<<endl;

    system("pause");
    return 0;

}

找零钱问题

我们知道人民币有1、2、5、10、20、50、100这几种面值。现在给你n(1≤n≤250)元,让你计算换成用上面这些面额表示且总数不超过100张,共有几种。比如4元,能用4张1元、2张1元和1张2元、2张2元,三种表示方法。
采用回溯法求解问题,算法思想同N皇后。

#include <stdio.h>
#include <iostream>
using namespace std;
int a[7]={1,2,5,10,20,50,100};
int temp[7]={0};
int total=0;
int count=0;
void function(int sum, int index) {
    int j,i;

    if (sum==total) {
        int pices=0;
        for(int x=0;x<7; x++) pices +=temp[x];
         if(pices<=100) count++;
        return;
    }
    else if (sum>total) return;
    else{
        for (i=index;i<7;i++) {
            temp[i]++;
            function(sum+a[i],i);
            temp[i]--;
        }
    }
}

int  main() {
    cin>>total;
    while(total!=0){
        count=0;
        function(0,0);
        cout<<count<<endl;
        cin>>total;
    }
return 0;
}

**计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得Ti

#include <iostream>
 #include <algorithm>
 using namespace std;
 int main()
 {
    int n,arr[100],answer=0;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>arr[i];

    int *listrise=new int[n];       //求最长上升子序列

    for (int i=0;i<n;i++)
    {
        listrise[i]=1;
        for (int j=0;j<i;j++)
        {
            if ((arr[i]>arr[j])&&(listrise[j]+1>listrise[i]))
                listrise[i]=listrise[j]+1;
        }
    }

    int *listdown=new int[n];   //求最大下降子序列
    for (int i=n-1;i>=0;i--)
    {
        listdown[i]=1;
        for (int j=n-1;j>i;j--)
        {
            if ((arr[i]>arr[j])&&(listdown[j]+1>listdown[i]))
                listdown[i]=listdown[j]+1;
        }
    }

    for(int i=0;i<n;i++)  
        if(listrise[i]+listdown[i]-1>answer)   
            answer=listrise[i]+listdown[i]-1;  
    cout<<n-answer<<endl;

    system("pause");
    return 0;
 }
*/

//统计某个整数二进制中 0的个数
#include<iostream>
#include<stdio.h>
#include<string>

using namespace std;

int main(){
    unsigned int test;
    cin>>test;
    int count=0;
    while(test!=0){
        if((test&0x1)==0) count++;
        test = test>>1;
    }
    cout<<count<<endl;
    system("pause");
    return 0;

}
*/
//统计不同行字符的个数
#include<iostream>
#include<stdio.h>
#include<string>

using namespace std;

int main(){
    string str;
    char result[256]={0};
    cin>>str;
    size_t len= str.length();
    if(len<=0) return 1;
    //int k=0;
    for(int i=0; i<len; i++){
        result[str[i]]=1;
    }

    int count=0;
    for(int j=0; j<256; j++){
        if(result[j]==1) count++;
    }

    cout<<count<<endl;
    system("pause");
    return 0;
}*/

Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。
输入:
Lily使用的图片包括”A”到”Z”、”a”到”z”、”0”到”9”。输入字母或数字个数不超过1024。
输出:
Lily的所有图片按照从小到大的顺序输出

样例输入:
Ihave1nose2hands10fingers
样例输出:
0112Iaadeeefghhinnnorsssv

#include<iostream>
#include<stdio.h>
#include <algorithm>  
using namespace std;

int main(){
    char instr[1024]={0};
    scanf("%s",instr);
    int len=strlen(instr);

    sort(instr,instr+len);

    for(int i=0; i<len; i++) 
        cout<<instr[i];
    system("pause");
    return 0;

}*/

查找出所有大于1小于等于整数m(m < 100)的非素数。 例如,若输入:17,则应输出:4 6 8 9 10 12 14 15 16。
输入:
输入一个大于1小于100的整数,如 17。
输出:
输出所有查找到的非素数。
样例输入:
17
样例输出:
4 6 8 9 10 12 14 15 16

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

int main(){
    int num=0;
    cin>>num;
    if(num<=1) return 0;
    for(int i=2; i<=num; i++ ){
        for(int k=2; k<i; k++)
            if(i%k==0){
                cout<<i<<' ';
                break;
            }   
    }
//system("pause");
return 0;

}*/
//计算最大公约数,利用辗转相除法
#include<iostream>
#include<stdio.h>
using namespace std;


int gcd(int a, int b){
    int temp=0;

    if(a < b){
        temp=a;
        a=b;
        b=temp;
    }
    while(b!=0){
        temp = a%b;
        a=b;
        b=temp;
    }
    return a;
}

int main(){
    int num1,num2;

    cin>>num1>>num2;

    cout<<gcd(num1,num2);

//  system("pause");
return 0;

}*/

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);

/*
功能: 求解放置8皇后方案的个数。
输入:
    无
返回:
    int:放置8皇后方案的个数
*/

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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值