<C/C++算法>九度OJ题目1465--1515解题练习(九)

题目1465:最简真分数

题目描述:

给出n个正整数,任取两个数分别作为分子和分母组成最简真分数,编程求共有几个这样的组合。

输入:

输入有多组,每组包含n(n<=600)和n个不同的整数,整数大于1且小于等于1000。
当n=0时,程序结束,不需要处理这组数据。


分析:

这是一个典型的最大公约数应用,显然真分数的分子和分母的最大公约数只能是1

输出:

每行输出最简真分数组合的个数。

样例输入:
7
3 5 7 9 11 13 15
3 
2 4 5
0
样例输出:
17 
2

欧几里得算法

#include "vector"
#include "string"
#include "algorithm"
#include <iostream>
#include "stack"
#include "math.h"  
 
usingnamespace std;
 
intEuclid(intmin, intmax)
{//判断是否是真分数:依据就是最大公约数是1,那就是真分数
    if(max == 0)
        returnmin;
    else
        returnEuclid(max,min%max);
}
intmain()
{
    intn = 0;
    while(cin >> n)
    {
        if(n == 0)
            break;
        vector<int> vec(n);
        for(inti = 0; i < n; i++)
            cin >> vec[i];
        sort(vec.begin(),vec.end());
        intcount = 0;
 
 
        for(vector<int>::iterator it = vec.begin() + 1; it != vec.end(); it++) 
            for(vector<int>::iterator jt = vec.begin(); jt != it; jt++)
                if(Euclid(*jt, *it)==1)//最大公约数是1,那么就是真分数
                    count++;
        cout << count << endl;
    }
         
    return0;
}
/**************************************************************
    Problem: 1465
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:100 ms
    Memory:1520 kb
****************************************************************/

暴力破解

#include "vector"
#include "string"
#include "algorithm"
#include <iostream>
#include "stack"
#include "math.h"  
 
using namespace std;
 
bool isTrueFen(int min, int max)
{//判断是否是真分数:依据就是从2开始是否有共同的约数
    if (min == 1 && max > 1)
        return true;
    for (int i = 2; i <= min; i++)
    {
        if (min%i == 0 && max%i == 0)
            return false;
    }
    return true;
}
int main()
{
    int n = 0;
    while (cin >> n)
    {
        if (n == 0)
            break;
        vector<int> vec(n);
        for (int i = 0; i < n; i++)
            cin >> vec[i];
        sort(vec.begin(),vec.end());
        int count = 0;
 
 
        for (vector<int>::iterator it = vec.begin() + 1; it != vec.end(); it++) 
        {
            for (vector<int>::iterator jt = vec.begin(); jt != it; jt++)
            {
                if (isTrueFen(*jt, *it))
                    count++;
            }
        }
         
        cout << count << endl;
    }
         
    return 0;
}
/**************************************************************
    Problem: 1465
    User: EbowTang
    Language: C++
    Result: Time Limit Exceed
****************************************************************/


题目1467:二叉排序树

题目描述:

        二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树:


        1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;
        2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值;
        3. 左、右子树本身也是一颗二叉排序树。


  现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。

输入:

输入包含多组测试数据,每组测试数据两行。
第一行,一个数字N(N<=100),表示待插入的节点数。
第二行,N个互不相同的正整数,表示要顺序插入节点的关键字值,这些值不超过10^8。

输出:

输出共N行,每次插入节点后,该节点对应的父亲节点的关键字值。

样例输入:
5
2 5 1 3 4
样例输出:
-1
2
2
5
3
#include "queue"
#include "vector"
#include "string"
#include "algorithm"
#include <iostream>
#include "stack"
#include <cmath>
#include <set>
 
using namespace std;
 
// 节点定义  
class BSTNode
{
public:
    BSTNode(int newData )// 默认构造  
    {
        pRight = NULL;
        pLeft = NULL;
        pParent = NULL;
        value = newData;
    }
    ~BSTNode();
    friend class LinkBST;// 允许链表类随意访问节点数据  
 
private:
    int value;
    BSTNode *pRight;
    BSTNode *pLeft;
    BSTNode *pParent;
};
 
// 有头结点的二叉搜索树定义   
class LinkBST
{
public:
    LinkBST(){
        m_pRoot = NULL;
    };
    ~LinkBST(){};
    BSTNode* getRoot() const
    {
        return m_pRoot;
    }
    // 插入节点
    void InsertBTNode(int newData);
 
private:
    BSTNode *m_pRoot;
};
 
// 插入节点
void LinkBST::InsertBTNode(int newData)
{
    BSTNode *newNode = new BSTNode(newData);
 
    if (m_pRoot == NULL)
    {
        m_pRoot = newNode;
        cout << "-1" << endl;
        return;
    }
 
    BSTNode *pPre = NULL;//用于保存上一个节点    
    BSTNode *pCur = m_pRoot;
    //寻找要插入的节点的位置 (一定是某个叶子)  
    while (pCur != NULL)
    {
        pPre = pCur;//保存节点  
        if (newNode->value < pCur->value)
            pCur = pCur->pLeft;//较小值则移到节点的左子树    
        else if (newNode->value > pCur->value)
            pCur = pCur->pRight;
    }
 
    //建立连接
    if (newNode->value < pPre->value)
        pPre->pLeft = newNode;
    else if (newNode->value > pPre->value)
        pPre->pRight = newNode;
 
    newNode->pParent = pPre;
    cout << newNode->pParent->value << endl;
}
 
 
int main()
{
    int n = 0;
    while (cin >> n)
    {
        LinkBST bst;
        int val = 0;
        for (int i = 0; i < n; i++)
        {
            cin >> val;
            bst.InsertBTNode(val);
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1467
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:20 ms
    Memory:1520 kb
****************************************************************/




题目1471:合并符串

题目描述:

给定两个字符串S1和S2,合并成一个新的字符串S。
合并规则为,S1的第一个字符为S的第一个字符,将S2的最后一个字符作为S的第二个字符;
将S1的第二个字符作为S的第三个字符,将S2的倒数第二个字符作为S的第四个字符,以此类推。

输入:

包含多组测试数据,每组测试数据包含两行,代表长度相等的两个字符串S1和S2(仅由小写字母组成,长度不超过100)。


分析:

简单模拟题

输出:

合并后的新字符串S

样例输入:
abc
def
样例输出:
afbecd

#include "string"
#include <iostream>
using namespace std;
 
 
int main()
{
    string str1,str2;
    while (cin>>str1>>str2)
    {
        int len1 = str1.size();
        int len2 = str2.size();
        string str(len1+len2,'0');//准备存放结果
     
        int i = 0, j = 0;
        while (i < len1)
        {
            str[j] = str1[i++];//放在偶数下标的位置
            j = j + 2;
        }
 
        i = len2 - 1, j = 1;
        while (i >= 0)
        {
            str[j] = str2[i--];//放在基数下标的位置
            j = j + 2;
        }
        cout << str << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1471
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1520 kb
****************************************************************/



题目1480:最大上升子序列和

题目描述:

一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ...,aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中序列和最大为18,为子序列(1, 3, 5, 9)的和.

你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和为100,而最长上升子序列为(1, 2, 3)。

输入:

输入包含多组测试数据。
每组测试数据由两行组成。第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000(可能重复)。

输出:

对于每组测试数据,输出其最大上升子序列和。

样例输入:
7
1 7 3 5 9 4 8
样例输出:
18

#include"iostream"
#include <stdio.h>  
using namespace std;
 
int data[1001];
int dp[1001];//第1个元素到第i个元素的最大不降和
int N = 0;
int MaxLongNoDrop()
{
    int max = -1;
    for (int i = 1; i <= N; ++i)
    {
        dp[i] = data[i];
        for (int j = 1; j < i; ++j)
        {
            if (data[i] > data[j] && dp[i] < dp[j] + data[i])
            {
                dp[i] = dp[j] + data[i];
                if (max < dp[i])
                    max = dp[i];
            }
        }
    }
     
    return max;
}
 
int main(void)
{
    while (cin>>N)
    {
        for (int i = 1; i <= N; ++i)
            cin>>data[i];
        cout << MaxLongNoDrop() << endl;
    }
 
    return 0;
}
/**************************************************************
    Problem: 1480
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:40 ms
    Memory:1528 kb
****************************************************************/

题目1483:求最大最小数

题目描述:

输入N个(N<=10000)数字,求出这N个数字中的最大值和最小值。每个数字的绝对值不大于1000000。

输入:

输入包括多组测试用例,每组测试用例由一个整数N开头,接下去一行给出N个整数。

输出:

输出包括两个整数,为给定N个数中的最大值与最小值。

样例输入:
5
1 2 3 4 5
3
3 7 8
样例输出:
5 1
8 3
#include <iostream>  
#include "stack"  
#include <cmath>  
#include <set>  
 
 
using namespace std;
 
int main()
{
    int n = 0;
    while (cin >> n, n > 0 && n <= 10000)
    {
        int tmp = 0;
        int maxnum = -10000;
        int minnum = 99999;
        for (int i = 0; i < n; i++)
        {
            cin >>tmp;
            if (maxnum < tmp)
                maxnum = tmp;
            if (minnum>tmp)
                minnum = tmp;
        }
        cout << maxnum << " " << minnum << endl;
 
    }
}
/**************************************************************
    Problem: 1483
    User: EbowTang
    Language: C++
    Result: Output Limit Exceed
****************************************************************/




题目1489:计算两个矩阵的乘积

题目描述:

计算两个矩阵的乘积,第一个是2*3,第二个是3*2

输入:

输入为两个矩阵,其中一个为2*3的矩阵,另一个为3*2的矩阵

输出:

一个2*2的矩阵(每一个数字后都跟一个空格)

样例输入:
1 2 3
3 4 5
6 7
8 9
10 11
样例输出:
52 58
100 112

#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
   
int Matrix1[2][3];  
int Matrix2[3][2];  
   
int main () {  
    int i,j,k;  
    int row = 2,col = 3;  
    while(scanf("%d %d %d",&Matrix1[0][0],&Matrix1[0][1],&Matrix1[0][2]) != EOF){  
        int Matrix3[2][2] = {0};  
        //输入第一个矩阵  
        for(i = 1;i < row;i++){  
            for(j = 0;j < col;j++){  
                scanf("%d",&Matrix1[i][j]);  
            }  
        }  
        //输入第二个矩阵  
        for(i = 0;i < col;i++){  
            for(j = 0;j < row;j++){  
                scanf("%d",&Matrix2[i][j]);  
            }  
        }  
        //相乘  
        for(i = 0;i < row;i++){  
            for(j = 0;j < row;j++){  
                for(k = 0;k < col;k++){  
                    Matrix3[i][j] += Matrix1[i][k] * Matrix2[k][j];  
                }  
            }  
        }  
           
        //输出  
        for(i = 0;i < row;i++){  
            for(j = 0;j < row;j++){  
                printf("%d ",Matrix3[i][j]);  
            }  
            printf("\n");  
        }  
    }  
    return 0;  
} 
/**************************************************************
    Problem: 1489
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1020 kb
****************************************************************/

题目1490:字符串链接

题目描述:

不用strcat 函数,自己编写一个字符串链接函数MyStrcat(char dstStr[],charsrcStr[])

输入:

两个字符串,字符串由小写字母组成。

输出:

链接后的字符串

样例输入:
hello world
good morning
样例输出:
helloworld
goodmorning

#include "string"
#include "algorithm"
#include <iostream>
 
using namespace std;
 
int MyStrcat(char dstStr[], char srcStr[])
{
    char *pdst = dstStr;
    char *psrc = srcStr;
    int len1 = strlen(dstStr);
    int len2 = strlen(srcStr);
    int i, j;
    for ( i = len1, j = 0; j < len2; j++, i++)
        dstStr[i] = srcStr[j];
    dstStr[i] = '\0';
    return 0;
}
int main()
{
    char src1[200] = {'\0'}, src2[100] = { '\0' };
    while (cin>>src1>>src2)
    {
        MyStrcat(src1,src2);
        cout << src1 << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1490
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/

题目1493:公约数

题目描述:

给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。
如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。

输入:

输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。

输出:

对于每组测试数据,输出为一个整数,表示a和b的公约数个数。

样例输入:
8 16
22 16
样例输出:
4
2

超时版本

#include "stdio.h"
#include <iostream>
#include "vector"
using namespace std;
 
int EUCLID(int a, int b)//欧几里得算法计算最大公约数
{
    if (b == 0)
        return a;
    else
        return EUCLID(b, a%b);
}
 
int main() 
{
    int a, b;
    int i;
    while (cin >> a >> b)
    {
        int count = 0;
        int maxGcd = EUCLID(a, b);//把最大公约数计算出来
        for (i = 1; i  <= maxGcd; ++i)
        {//计算公共公约数
            if (a%i == 0 && b%i == 0)
                count++;
        }
        cout << count << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1493
    User: EbowTang
    Language: C++
    Result: Time Limit Exceed
****************************************************************/

非超时版本

#include <iostream>
#include "vector"
using namespace std;
 
int EUCLID(int a, int b)//欧几里得算法计算最大公约数
{
    if (b == 0)
        return a;
    else
        return EUCLID(b, a%b);
}
 
int main() 
{
    int a, b;
    int count;
    int i;
    while (cin >> a >> b)
    {
        count = 0;
        int maxGcd = EUCLID(a, b);//把最大公约数计算出来
        for (i = 1; i * i < maxGcd; ++i)
        {
            if (maxGcd % i == 0)
                count += 2;
        }
        if (i * i == maxGcd)
            ++count;
        cout << count << endl;
 
    }
    return 0;
}
/**************************************************************
    Problem: 1493
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:30 ms
    Memory:1520 kb
****************************************************************/


题目1499:项目安排

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:790

解决:246

题目描述:

小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的money来充实钱包。万能的网友麻烦你来帮帮小明,如何在最短时间内安排自己手中的项目才能保证赚钱最多(注意:做项目的时候,项目不能并行,即两个项目之间不能有时间重叠,但是一个项目刚结束,就可以立即做另一个项目,即项目起止时间点可以重叠)。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入的第一行是一个整数n(1<=n<=10000):代表小明手中的项目个数。
接下来共有n行,每行有3个整数st、ed、val,分别表示项目的开始、截至时间和项目的报酬,相邻两数之间用空格隔开。
st、ed、value取值均在32位有符号整数(int)的范围内,输入数据保证所有数据的value总和也在int范围内。

输出:

对应每个测试案例,输出小明可以获得的最大报酬。

样例输入:
3
1 3 6
4 8 9
2 5 16
4
1 14 10
5 20 15
15 20 8
18 22 12
样例输出:
16
22
提示:
#include "vector"  
#include <iostream>  
#include "algorithm"  
#include<string>
#include <stdio.h>
#include<cmath>
#include<cstdlib>
 
using namespace std;
 
 
//动态规划问题:
//令dp[i]为在前i个项目下能获得的最大利润
//对于第i个项目,如果前面第j个项目满足时间条件,我们可以做,也可以不做
//如果不做第i个项目,那就不变,和前一次一样,dp[i]=dp[i-1](不是dp[i])
//如果做第i个项目,并且满足第j个项目时间,dp[i]=dp[j] + pro[i].value
 
class Item
{
public:
    int st;
    int ed;
    int value;
};
 
int cmp(Item x, Item y)
{
    return x.ed<y.ed;//按照结束时间排序
}
 
int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        vector<int> dp(n+1,0);
        Item pro[10001];
        int i, j;
        for (i = 1; i <= n; i++)
            scanf("%d%d%d", &pro[i].st, &pro[i].ed, &pro[i].value);
 
        sort(pro+1, pro+n+1, cmp);//类似贪心处理
 
        dp[1] = pro[1].value;
 
        for (i = 2; i <= n; i++)
        {
            for (j = i - 1; j >= 1; j--)//必须逆序
                if (pro[j].ed <= pro[i].st)//只要第i个项目前面的某个项目满足条件
                    break;
             
            dp[i] = max(dp[j] + pro[i].value, dp[i - 1]);
        }
        printf("%d\n", dp[n]);
    }
    return 0;
}
/**************************************************************
    Problem: 1499
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:260 ms
    Memory:1576 kb
****************************************************************/






题目1504:把数组排成最小的数

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:1776

解决:561

题目描述:

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数。
输入的第二行包括m个正整数,其中每个正整数不超过10000000。

输出:

对应每个测试案例,
输出m个数字能排成的最小数字。

样例输入:
3
23 13 6
2
23456 56
样例输出:
13236
2345656
#include "vector"  
#include <iostream>  
#include "algorithm"  
#include<string>
#include <stdio.h>
#include<cmath>
#include<cstdlib>
 
using namespace std;
 
 long long numbers[200];
string str_num[200];
 
//不能简单的按字典序排序即小的在前面。
//比如32的字典序比322小,但是32322比32232大,
bool cmp(const string &str1, const string &str2) 
{
    string _str1 = str1;
    string _str2 = str2;
    _str1.append(str2);//在_str1后面追加str2字符串
    _str2.append(str1);
    return _str1 < _str2;//true则将对原字符串顺序颠倒,否则不处理
}
 
int main() {
    int n;
    while (scanf("%d", &n) != EOF) 
    {
        //接受输入
        for (int i = 0; i < n; i++)
            scanf("%d", numbers + i);
 
        for (int i = 0; i < n; i++) 
        {
            char str[20];
            sprintf(str, "%d", numbers[i]);//将数字转换到str内存中
            str_num[i] = str;
        }
 
        sort(str_num, str_num + n, cmp);
 
        for (int i = 0; i < n; i++) 
            cout << str_num[i];
         
        cout << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1504
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:220 ms
    Memory:1524 kb
****************************************************************/





题目1506:求1+2+3+...+n

题目描述:

求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入为一个整数n(1<= n<=100000)。

输出:

对应每个测试案例,
输出1+2+3+…+n的值。

样例输入:
3
5
样例输出:
6
15

C++多态性方法

#include <iostream>
#include "algorithm"
  
using namespace std;
 
class BaseAdd;
BaseAdd* Array[2];//两个基类指针
 
class BaseAdd
{
public:
    virtual int Sum(int n)//虚函数
    {
        return 0;//递归截止条件
    }
};
 
class DerAdd :public BaseAdd
{
public:
    virtual int Sum(int n)//覆盖基类虚函数
    {
        //当n=0时,Array[!!n]=Array[0],他存储的就是基类的对象地址,显然调用的是基类的Sum函数
        //当n=1时,Array[!!n]=Array[1],他存储的是派生类的对象地址,将会调用派生类的函数
        return Array[!!n]->Sum(n - 1) + n;//按题目要求实现“循环”只能用递归了
    }
};
 
int solutionSum(int n)
{
    BaseAdd a;
    DerAdd b;
    Array[0] = &a;
    Array[1] = &b;//根据动态绑定,在程序运行时再确定具体调用哪一个函数
    int nSum = Array[1]->Sum(n);
    return nSum;
}
 
int main()
{
    int n = 0;
    while (cin >> n)
        cout << solutionSum(n) << endl;
    return 0;
}
/**************************************************************
    Problem: 1506
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:880 ms
    Memory:1628 kb
****************************************************************/

朴素的递归方法

#include <iostream>
using namespace std;
//错误的解法:使用递归
//参考http://blog.csdn.net/wusuopubupt/article/details/17714705
int add(int n, int *pSum) 
{//n==0就停止递归
    n && add(n - 1, pSum);//递归(很遗憾当n=5000时就栈溢出了)
    return (*pSum += n);//实现计算
}
int main()
{
    int n = 0;
    while (cin>>n)
    {
        int sum = 0;
        add(n, &sum);
        cout << sum << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1506
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:710 ms
    Memory:1820 kb
****************************************************************/


题目1507:不用加减乘除做加法


题目描述:

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入为两个整数m和n(1<=m,n<=1000000)。

输出:

对应每个测试案例,输出m+n的值。

样例输入:
3 4
7 9
样例输出:
7
16

位运算方法

#include <iostream>
#include "algorithm"
  
using namespace std;
 
 
int solutionAdd(int n,int m)
{
    int num1 = 0, num2;
    do
    {//举例5+17,5(101),17(10001)
        num1 = n^m; //模拟二进制中各位相加(但不进位), 异或(不同则为真,结果为10100
        num2 = (n & m) << 1;//获取模拟进位结果,因为只有相应位同时为1时才能为真,所以让结果往左移,结果00010
        n = num1;
        m = num2;
    } while (num2 != 0);//如果还有进位,就再加上进位
    return num1;
}
 
int main()
{
    int n = 0, m = 0;
    while (cin >> n >> m)
        cout << solutionAdd(n,m) << endl;
    return 0;
}
/**************************************************************
    Problem: 1507
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:50 ms
    Memory:1520 kb
****************************************************************/


题目1508:把字符串转换成整数

题目描述:

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入为一个合法或者非法的字符串,代表一个整数n(1<= n<=10000000)。

输出:

对应每个测试案例,
若输入为一个合法的字符串(即代表一个整数),则输出这个整数。
若输入为一个非法的字符串,则输出“My God”。


分析:

本题考虑问题要尽可能全面

样例输入:
5
-5
+8
样例输出:
5
-5
8

#include "string"
#include "algorithm"
#include <iostream>
 
#include <cstdio>
using namespace std;
 
int main()
{
    string str;
    while (cin>>str)
    {
        bool sig = true, con = true;
        int ans = 0;
        if (str[0]=='-')
        {
            sig = false;
        }
        else if (str[0] == '+')
        {
 
        }
        else if (str[0] <= '9' && str[0] >='0')
        {
            ans = ans * 10;
            ans = ans + str[0] - '0';
        }
        else//其他任何情况都是错误的
        {
            con = false;
        }
        int i = 1;
 
        if (con)
        {
            while (i < str.size())
            {
                if (str[i] >= '0' && str[i] <= '9')
                {
                    ans = ans * 10; 
                    ans+=str[i++] - '0';
                }
                else
                {//在第二个字符及其后面发现异常
                    con = false;
                    break;
                }
            }
        }
 
        if (con)//要么输出异常,要么输出答案
        {
            if (!sig)
                ans = -1 * ans;
            cout << ans << endl;
        }
        else
        {
            cout << "My God" << endl;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1508
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:50 ms
    Memory:1520 kb
****************************************************************/

题目1510:替换空格


题目描述:

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

输入:

每个输入文件仅包含一组测试样例。
对于每组测试案例,输入一行代表要处理的字符串。

输出:

对应每个测试案例,出经过处理后的字符串。

样例输入:
We Are Happy
样例输出:
We%20Are%20Happy

#include "string"
#include <iostream>
 
using namespace std;
 
int main()
{
    string str;
    while (getline(cin,str))
    {
        string sub("%20");
        for (int i = 0; i < str.size(); i++)
        {
            if (str[i]==' ')
                str.replace(i,1,sub);//从字符串str第i个位置起,及其后面k(这里是1)个字符串替换为sub
        }
        cout << str << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1510
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:890 ms
    Memory:2284 kb
****************************************************************/


题目1512:用两个栈实现队列

题目描述:

用两个栈来实现一个队列,完成队列的Push和Pop操作。
队列中的元素为int类型。

输入:

每个输入文件包含一个测试样例。
对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数。
接下来的n行,每行输入一个队列操作:
1. PUSH X 向队列中push一个整数x(x>=0)
2. POP 从队列中pop一个数。

输出:

对应每个测试案例,打印所有pop操作中从队列pop中的数字。如果执行pop操作时,队列为空,则打印-1。

样例输入:
3
PUSH 10
POP
POP
样例输出:
10
-1

超时版本:

#include "string"
#include "algorithm"
#include <iostream>
#include "stack"
#include <cmath>
#include <set>
 
using namespace std;
 
class QueueByStack
{
public:
    QueueByStack(){};
    ~QueueByStack(){};
    void push(int n);
    void pop();
private:
    stack<int> s1;//辅助栈
    stack<int> s2;//执行栈
};
 
void QueueByStack::push(int n)
{
    if (s2.empty())//直接压栈即可
    {
        s2.push(n);
    }
    else
    {
        while (!s2.empty())//依次弹出给栈s1,并使s2为空
        {
            int num = s2.top();
            s2.pop();//删除栈顶值
            s1.push(num);
        }
 
        s2.push(n);//空的s2获得新数n
 
        while (!s1.empty())//依次弹出给栈s2,并使s1为空
        {
            int num = s1.top();
            s1.pop();
            s2.push(num);
        }
    }
}
 
void QueueByStack::pop()
{
    if (s2.empty())
    {
        cout << -1 << endl;
    }
    else
    {
        cout << s2.top() << endl;
        s2.pop();//删除栈顶值
    }
}
 
 
 
int main()
{
    int n = 0;
    while (cin >> n)
    {
        cin.get();//换新行准备让str接收字符,如果没有将错误,找了好久才发现,他妈的
        QueueByStack qs;
        string str;
        int num = 0;
        for (int i = 0; i < n; i++)
        {
            cin >> str;
            if (str == "POP")
            {
                qs.pop();
            }
            else
            {
                cin >> num;
                qs.push(num);
            }
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1512
    User: EbowTang
    Language: C++
    Result: Time Limit Exceed
****************************************************************/






题目1513:二进制中1的个数

题目描述:

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

输入:

输入可能包含多个测试样例。
对于每个输入文件,第一行输入一个整数T,代表测试样例的数量。对于每个测试样例输入为一个整数。
。n保证是int范围内的一个整数。

输出:

对应每个测试案例,
输出一个整数,代表输入的那个数中1的个数。

样例输入:
3
4
5
-1
样例输出:
1
2
32

位运算方法

#include <stdio.h>  
    
int Count (int n){  
    int cnt = 0;  
    while (n){  
        ++cnt;  
        n &= (n - 1);  
    }  
    return cnt;  
}  
    
int main(void){  
    int T;  
    int n;  
    
    while (scanf ("%d", &T) != EOF){  
        while (T-- != 0){  
            scanf ("%d", &n);  
            printf ("%d\n", Count (n));  
        }  
    }  
    
    return 0;  
} 
 
/**************************************************************
    Problem: 1513
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:90 ms
    Memory:1020 kb
****************************************************************/


题目1515:打印1到最大的N位数

题目描述:

给定一个数字N,打印从1到最大的N位数。

输入:

每个输入文件仅包含一组测试样例。
对于每个测试案例,输入一个数字N(1<=N<=5)。

输出:

对应每个测试案例,依次打印从1到最大的N位数。

样例输入:
1
样例输出:
1
2
3
4
5
6
7
8
9

#include "iostream"
#include "stdio.h"
#include "vector"
#include "algorithm"
using namespace std;
int getMaxBitNum(int N)
{
    int res = 0;
 
    for (size_t i = 0; i < N; i++)
    {
        res = res * 10;
        res = res + 9;
    }
    return res;
}
int main()
{
    int N = 0;
    while (cin >> N)
    {
        if (N > 5 || N < 1)
            break;
        for (size_t i = 1; i <= getMaxBitNum(N); i++)
            printf("%d\n", i);
    }
    return 0;
}
/**************************************************************
    Problem: 1515
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:50 ms
    Memory:1520 kb
****************************************************************/





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值