九度OJ题目1050--1100解题练习(三)

题目1050:完数

题目描述:

    求1-n内的完数,所谓的完数是这样的数,它的所有因子相加等于它自身,比如6有3个因子1,2,3,1+2+3=6,那么6是完数。即完数是等于其所有因子相加和的数。

输入:

    测试数据有多组,输入n,n数据范围不大。

输出:

    对于每组输入,请输出1-n内所有的完数。如有案例输出有多个数字,用空格隔开,输出最后不要有多余的空格。


方法:

根据题意直接写程序

样例输入:
6
样例输出:
6
C++程序实现如下:

#include 
#include "vector"
using namespace std;
 
int printPerNum(int n);
bool IsPerNum(const int m);
int main()
{
    int n = 0;
    while (cin >> n)
    {
        printPerNum(n);
    }
    return 0;
}
 
int printPerNum(int n)
{
    for (int i = 1; i <= n;i++)
    {
        if (IsPerNum(i))//判断该数是否是完数
        {
            if (i != 6)//控制空格的出现
            {
                cout << " ";
            }
            cout << i;//若是就输出
        }
    }
    cout << endl;
    return -1;
}
 
bool IsPerNum(const int m)
{
    bool ans = false;
    vector facArr(1086,0);
    int count = 0;
    for (int i = 1; i <= m / 2;i++)//求因子
    {
        if (m % i == 0)
        {
            facArr[count] = i;
            count++;
        }
    }
    int sum = 0;
    for (unsigned int i = 0; i < count; i++)
    {
        sum = sum + facArr[i];
    }
    if (sum == m)
    {
        ans = true;
    }
    facArr.clear();
    return ans;
}
/**************************************************************
    Problem: 1050
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:140 ms
    Memory:1520 kb
****************************************************************/

题目1051:数字阶梯求和

题目描述:

给定a和n,计算a+aa+aaa+a...a(n个a)的和。

输入:

测试数据有多组,输入a,n(1<=a<=9,1<=n<=100)。

输出:

对于每组输入,请输出结果。

样例输入:
1 10
样例输出:
1234567900
#include 
#include "vector"
using namespace std;
 
int stepSum(vector &sumArr,int a,int n);
int main()
{
    int n = 0, a = 0;
    while (cin >>a>>n)
    {
        if (a>9 || a<0 || n>100 || n < 0)
        {
            break;
        }
 
        vector sumArr(n+1,0);//注意长度不能是n
 
        stepSum(sumArr,a,n);
 
        /*//不要用这种遍历方式
        for (unsigned int i = n-1; i >= 0; --i)
        {
            cout << sumArr[i];
        }*/
        for (unsigned int i = 0; i < n+1; i++)
        {
            if (sumArr[n] == 0 && (n - i) == n)// 跳过sumArr[n]==0的情况
            {
                continue;
            }
            cout << sumArr[n-i];
        }
        cout << endl;
        sumArr.clear();
    }
    return 0;
}
 
int stepSum(vector &sumArr, int a, int n)
{
    for (int i = 1; i <= n;i++)//此加法公式中有n个数
    {
        for (int j = 0; j < i;j++)
        {
            sumArr[j] = sumArr[j] + a;
        }
    }
    for (int i = 0; i < n; i++)// 这里实现进位操作  
    {
        if (sumArr[i] >= 10)
        {
            sumArr[i+1] += sumArr[i] / 10;//让高位获得来自低位的进位值 
            sumArr[i] %= 10;//低位自裁,只保留当前数的个位即可,比如223,只保留3,22给高位  
        }
    }
 
    return -1;
}
/**************************************************************
    Problem: 1051
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1520 kb
****************************************************************/


题目1052:找x

题目描述:

输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。

输入:

测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。

输出:

对于每组输入,请输出结果。

样例输入:
2
1 3
0
样例输出:
-1

C++程序实现如下:

#include   
#include 
#include 
using namespace std;
int getPos(vector &v,int x);
int main()
{
    int n;
    while (cin >> n)
    {
        vector vIn(n);//创建n个空元素
        for (int i = 0; i < n; ++i)//获取n个元素
        {
            cin >> vIn[i];
        }
 
        int x = 0;
        cin >> x;
         
        int pos = getPos(vIn,x);
        cout << pos << endl;
    }
    return 0;
}
 
int getPos(vector &v,int x)
{
    for (unsigned int i = 0; i < v.size();i++)
    {
        if (v[i]==x)
        {
            return i;
        }
    }
    return -1;//error
}
/**************************************************************
    Problem: 1052
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1520 kb
****************************************************************/


题目1053:互换最大最小数

题目描述:

输入一个数n,然后输入n个数值各不相同,调换数组中最大和最小的两个数,然后输出。

输入:

测试数据有多组,输入n(1<=n<=20),接着输入n个数。

输出:

对于每组输入,输出交换后的结果。

样例输入:
2
1 3
样例输出:
3 1
C++程序实现如下:

#include   
#include "vector"
#include 
using namespace std;
 
int main()
{
    int n = 0;
    while (cin>>n)
    {
        if (n > 20 || n < 0)
            break;
 
        vector v(n,0);
        for (int i = 0; i < n;i++)
            cin >> v[i];
        int min = 99999999,max=0;
        int posMin = 0, posMax = 0;
        for (int i = 0; i < n;i++)
        {
            if (max < v[i])
            {
                max = v[i];posMax = i;
            }
            if (min > v[i])
            {
                min = v[i]; posMin = i;
            }
        }
        swap(v[posMin], v[posMax]);
        for (int i = 0; i < n; i++)
        {
            if (i == n - 1)
                cout << v[i];
            else
                cout << v[i] << " ";
        }
        cout << endl;
        v.clear();
    }
    return 0;
}
/**************************************************************
    Problem: 1053
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1520 kb
****************************************************************/



题目1054:字符串内排序

题目描述:

输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串。

输入:

测试数据有多组,输入字符串。

输出:

对于每组输入,输出处理后的结果。


方法:

排序的简单运用

样例输入:
bacd
样例输出:
abcd
C++程序实现如下:

[html]  view plain copy print ?
  1. #include "string"  
  2. #include <iostream>    
  3. using namespace std;  
  4.    
  5.    
  6. int main()  
  7. {     
  8.     string s;  
  9.     while (cin>>s)//或者getline(cin,s)  
  10.     {  
  11.         if (s.length()>200)  
  12.         {  
  13.             break;  
  14.         }  
  15.         for (int i = s.length()-1; i >= 0;i--)//冒泡排序这个字符串  
  16.         {  
  17.             for (int j = 0; j < i;j++)  
  18.             {  
  19.                 if (s[j] < s[i])  
  20.                 {  
  21.                     char temp = s[j];  
  22.                     s[j] = s[i];  
  23.                     s[i] = temp;  
  24.                 }  
  25.             }  
  26.         }  
  27.    
  28.         for (int i = s.length() - 1; i >= 0;i--)//输出字符串  
  29.         {  
  30.             cout << s[i];  
  31.         }  
  32.         cout << endl;  
  33.     }  
  34.     return 0;  
  35. }  
  36. /**************************************************************  
  37.     Problem: 1054  
  38.     User: EbowTang  
  39.     Language: C++  
  40.     Result: Accepted  
  41.     Time:10 ms  
  42.     Memory:1520 kb  
  43. ****************************************************************/  


题目1055:数组逆置

题目描述:

输入一个字符串,长度小于等于200,然后将数组逆置输出。

输入:

测试数据有多组,每组输入一个字符串。

输出:

对于每组输入,请输出逆置后的结果。


方法:

利用string类,一瞬间就完成了

样例输入:
hdssg
样例输出:
gssdh
C++程序实现如下:

[html]  view plain copy print ?
  1. #include "string"  
  2. #include <iostream>    
  3. using namespace std;  
  4.    
  5.    
  6. int main()  
  7. {     
  8.     string s;  
  9.     while (cin>>s)//或者getline(cin,s)  
  10.     {  
  11.         if (s.length()>200)  
  12.         {  
  13.             break;  
  14.         }  
  15.         for (int i = s.length()-1; i >= 0;i--)  
  16.         {  
  17.             cout << s[i];  
  18.         }  
  19.         cout << endl;  
  20.     }  
  21.     return 0;  
  22. }  
  23. /**************************************************************  
  24.     Problem: 1055  
  25.     User: EbowTang  
  26.     Language: C++  
  27.     Result: Accepted  
  28.     Time:0 ms  
  29.     Memory:1520 kb  
  30. ****************************************************************/  


题目1056:最大公约数

题目描述:

输入两个正整数,求其最大公约数。

输入:

测试数据有多组,每组输入两个正整数。

输出:

对于每组输入,请输出其最大公约数。


方法:

欧几里得算法

样例输入:
49 14
样例输出:
7

C++程序实现如下:

[html]  view plain copy print ?
  1. #include <iostream>    
  2. using namespace std;  
  3.    
  4. int getGcd(int x,int y)  
  5. {  
  6.     //return (!y) ? x : getGcd(y, x%y);//碾转相除法  
  7.     if (y == 0)//欧几里得算法  
  8.     {  
  9.         return x;  
  10.     }  
  11.     else  
  12.     {  
  13.         return getGcd(y, x%y);  
  14.     }  
  15. }  
  16.    
  17. int main()  
  18. {     
  19.     int num1 = 0;  
  20.     int num2 = 0;  
  21.     while (cin >>num1)  
  22.     {  
  23.         cin >> num2;  
  24.         int ans = getGcd(num1, num2);  
  25.         cout << ans << endl;  
  26.     }  
  27.     return 0;  
  28. }  
  29. /**************************************************************  
  30.     Problem: 1056  
  31.     User: EbowTang  
  32.     Language: C++  
  33.     Result: Accepted  
  34.     Time:0 ms  
  35.     Memory:1520 kb  
  36. ****************************************************************/  


题目1057:众数

题目描述:

输入20个数,每个数都在1-10之间,求1-10中的众数(众数就是出现次数最多的数,如果存在一样多次数的众数,则输出权值较小的那一个)。

输入:

测试数据有多组,每组输入20个1-10之间的数。

输出:

对于每组输入,请输出1-10中的众数。

样例输入:
5 1 5 10 3 5 3 4 8 6 8 3 6 5 10 7 10 2 6 2 
样例输出:
5
C++程序实现如下:

#include   
#include "vector"
#include "string"
#include 
using namespace std;
 
int main()
{
    vector v(20,0);
    while (true)
    {
        for (int i = 0; i < 20; i++)
        {
            cin >> v[i];
            if (v[i]>10 || v[i] < 0)
            {
                break;
            }
        }
        vector v1(10, 0);//统计出现次数
 
        for (int i = 0; i < v.size();i++)
        {
            v1[v[i]-1]++;
        }
        int max = 0;
        int pos = 0;
        for (int i = 0; i < v1.size();i++)
        {
            if (max < v1[i])
            {
                max = v1[i];
                pos = i;
            }
        }
        cout << pos+1 << endl;
 
    }
}
/**************************************************************
    Problem: 1057
    User: EbowTang
    Language: C++
    Result: Output Limit Exceed
****************************************************************/


题目1058:反序输出

题目描述:

输入任意4个字符(如:abcd), 并按反序输出(如:dcba)

输入:

题目可能包含多组用例,每组用例占一行,包含4个任意的字符。

输出:

对于每组输入,请输出一行反序后的字符串。
具体可见样例。

样例输入:
Upin
cvYj
WJpw
cXOA
样例输出:
nipU
jYvc
wpJW
AOXc
C程序实现如下:

#include
int main()
{
    char t[5];
    while(gets(t))
        printf("%c%c%c%c\n",t[3],t[2],t[1],t[0]);
}
/**************************************************************
    Problem: 1058
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:40 ms
    Memory:1020 kb
****************************************************************/

为什么用C++却不行?(超时!!!)

#include "string"
#include   
using namespace std;
int main()
{
    string str;
 
    while (cin >> str)
    {
        for (int i = str.length() - 1; i >= 0;i--)
        {
            cout << str[i];
        }
        cout << endl;
        str.erase();
    }
    return 0;
}
/**************************************************************
    Problem: 1058
    User: EbowTang
    Language: C++
    Result: Time Limit Exceed
****************************************************************/

题目1059:abc

题目描述:

设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。

输入:

题目没有任何输入。

输出:

请输出所有满足题目条件的a、b、c的值。
a、b、c之间用空格隔开。
每个输出占一行。


方法:

简单穷举

样例输入:
 
    
样例输出:
C++程序实现如下:
#include   
using namespace std;
int main()
{
    for (int a = 0; a <= 9;a++)
    {
        for (int b = 0; b <= 9;b++)
        {
            for (int c = 0; c <= 9;c++)
            {
                if ((a * 100 + b * 10 + c + b * 100 + c * 10 + c) == 532)
                {
                    cout << a<<" " << b <<" "<< c << endl;
                }
            }
        }
    }
    return 0;
}
 
/**************************************************************
    Problem: 1059
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1516 kb
****************************************************************/

题目1060:完数VS盈数


题目描述:

一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1。则称其为“完数”;若因子之和大于该数,则称其为“盈数”。
求出2到60之间所有“完数”和“盈数”。

输入:

题目没有任何输入。

输出:

输出2到60之间所有“完数”和“盈数”,并以如下形式输出:
E: e1 e2 e3 ......(ei为完数)
G: g1 g2 g3 ......(gi为盈数)
其中两个数之间要有空格,行尾不加空格。

样例输入:
 
     
样例输出:
C++实现如下:
#include "iostream"
using namespace std;
int main(void)
{
    cout << "E:";
    for (int i = 2; i <= 60;i++)
    {
        int sum = 0;
        for (int j = 1; j <= i / 2;j++)
        {
            if (i%j == 0)
                sum = sum + j;
        }
        if (sum == i)
            cout<<" "<< i;
    }
    cout << endl;
    cout << "G:";
    for (int i = 2; i <= 60; i++)
    {
        int sum = 0;
        for (int j = 1; j <= i / 2; j++)
        {
            if (i%j == 0)
                sum = sum + j;
        }
        if (sum > i)
            cout<<" " << i;
    }
    cout << endl;
    return 0;
}
/**************************************************************
    Problem: 1060
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1516 kb
****************************************************************/

题目1061:成绩排序


题目描述:

    有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出N个学生排序后的信息。

输入:

    测试数据有多组,每组输入第一行有一个整数N(N<=1000),接下来的N行包括N个学生的数据。
    每个学生的数据包括姓名(长度不超过100的字符串)、年龄(整形数)、成绩(小于等于100的正数)。

输出:

    将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。
    然后输出学生信息,按照如下格式:
    姓名 年龄 成绩

样例输入:
3
abc 20 99
bcd 19 97
bed 20 97
样例输出:
bcd 19 97
bed 20 97
abc 20 99
提示:

学生姓名的字母序区分字母的大小写,如A要比a的字母序靠前(因为A的ASC码比a的ASC码要小)。

#include "string"
#include "vector"
#include
#include 
 
using namespace std;
 
typedef struct _StuInfo
{
    int age;
    int score;
    string name;
}StuInfo;
 
bool cmpStu(StuInfo x, StuInfo y)
{
    if (x.score != y.score)
        return x.score < y.score;
    else
    {
        if (x.name != y.name)
            return x.name>n)//人数
    {
        //获取数据
        for (int i = 0; i> a[i].name >> a[i].age>> a[i].score;
        //多关键字排序
        sort(a, a + n, cmpStu);//功能是先排分数,若相等则在其基础上对名字和年龄进行排序。
        //输出信息
        for (int i = 0; i




题目1062:分段函数

题目描述:

编写程序,计算下列分段函数y=f(x)的值。
y=-x+2.5; 0<=x<2
y=2-1.5(x-3)(x-3); 2<=x<4
y=x/2-1.5; 4<=x<6

输入:

一个浮点数N

输出:

测试数据可能有多组,对于每一组数据,
输出N对应的分段函数值:f(N)。结果保留三位小数

样例输入:
1
样例输出:
1.500


C++程序实现如下:
#include  //要用到格式控制符
#include
using namespace std;
 
int main(void)
{
    double x = 0.0, y = 0.0;
    while (cin >> x)
    {
        if (x >= 0 && x < 2)
            y = -x + 2.5;
        else if (x >= 2 && x < 4)
            y = 2 - 1.5*(x - 3)*(x - 3);
        else if (x >= 4 && x < 6)
            y = x / 2 - 1.5;
        else
            break;
        cout << fixed << setprecision(3) << y << endl;//控制精度并且输出
    //fixed和setprecision合用就是控制小数点后三位,若果无fixed则控制的整个长度为3
    }
    return 0;
}
/**************************************************************
    Problem: 1062
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:40 ms
    Memory:1520 kb
****************************************************************/

题目1063:整数和

题目描述:

编写程序,读入一个整数N。
若N为非负数,则计算N到2N之间的整数和;
若N为一个负数,则求2N到N之间的整数和

输入:

一个整数N,N的绝对值小于等于1000

输出:

测试数据可能有多组,对于每一组数据,
输出题目要求的值

样例输入:
1
-1
样例输出:
3
-3
#include   
#include "vector"
#include "string"
#include 
#include "math.h"
using namespace std;
 
int main()
{
    int n = 0;
    while (cin >> n)
    {
        if (abs(n)>1000)
        {
            break;
        }
        int sum;
        if (n>=0)
        {
            sum = 0;
            for (int i = n; i <= 2 * n;i++)
            {
                sum = sum + i;
            }
            cout << sum<


题目1064:反序数


题目描述:

设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321)
求N的值

输入:

程序无任何输入数据

输出:

输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开


方法:

简单穷举

样例输入:
 
    
样例输出:
C++程序实现如下:
#include   
using namespace std;
 
int  getN(int i,int j,int k,int m);
int  getRN(int i,int j,int k,int m);
 
int main()
{
    for (int i = 1; i <= 9;i++)
    {
        for (int j = 0; j <= 9;j++)
        {
            for (int k = 0; k <= 9;k++)
            {
                for (int m = 0; m <= 9;m++)
                {
                    int x = getN(i,j,k,m);
                    int y = getRN(i,j,k,m);
                    if (x * 9 == y)
                    {
                        cout << x << endl;
                    }
                }
            }
        }
    }
 
    return 0;
}
 
 
int  getN(int i, int j, int k, int m)
{
    return i * 1000 + j * 100 + k * 10 + m;
}
int  getRN(int i, int j, int k, int m)
{
    return m * 1000 + k * 100 + j * 10 + i;
}
/**************************************************************
    Problem: 1064
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1516 kb
****************************************************************/

题目1065:输出梯形


题目描述:

输入一个高度h,输出一个高为h,上底边为h的梯形。

输入:

一个整数h(1<=h<=1000)。

输出:

h所对应的梯形。

样例输入:
4
样例输出:
      ****
    ******
  ********
**********
提示:

梯形每行都是右对齐的,sample中是界面显示问题


#include
using namespace std;
 
int main(void)
{
    int h;
    while (cin >> h)
    {
        int i, j;
        for (i = 1; i <= h; i++)//输出h行
        {
            for (j = 1; j <= 2 * h - 2 * i; j++)//控制每一行的空格数
                cout<<" ";
            for (j = 2 * h - 2 * i + 1; j <= 3 * h - 2; j++)//控制每一行的星号数
                cout<<"*";
            cout << endl;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1065
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:190 ms
    Memory:1520 kb
****************************************************************/

题目1066:字符串排序

题目描述:

 输入一个长度不超过20的字符串,对所输入的字符串,按照ASCII码的大小从小到大进行排序,请输出排序后的结果

输入:

 一个字符串,其长度n<=20

输出:

 输入样例可能有多组,对于每组测试样例,

按照ASCII码的大小对输入的字符串从小到大进行排序,输出排序后的结果
样例输入:
dcba
样例输出:
abcd
#include   
#include "string"
#include 
using namespace std;
 
int main()
{
    string str;
    while (getline(cin,str))
    {
        if (str.size()>20)
            break;
        sort(str.begin(), str.end());
        for (int i = 0; i < str.size();i++)
            cout << str[i];
        cout <


题目1067:n的阶乘

题目描述:

输入一个整数n,输出n的阶乘

输入:

一个整数n(1<=n<=20)

输出:
n的阶乘
样例输入:
3
样例输出:
6
#include "iostream"
#include "string"
#include 
#include 
using namespace std;
int res[10010];
int main()
{
    int n;
    while (cin>>n)
    {
        int i, j;
        memset(res, 0, sizeof(res));//全部置零
        res[0] = 1;//f(0)
        res[1] = 1;//f(1)
 
        for (i = 2; i <= n; i++)
        {
            for (j = 1; j <= res[0]; j++)
            {
                res[j] = res[j] * i;
            }
            for (j = 1; j <= res[0]; j++)
            {
                if (res[j] >= 10)
                {
                    res[j + 1] += res[j] / 10;
                    res[j] %= 10;
                    if (j == res[0])
                    {
                        res[0]++;
                    }
                }
            }
        }
 
        for (i = res[0]; i >= 1; i--)
        {
            cout << res[i];
        }
        cout << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1067
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1556 kb
****************************************************************/

题目1068:球的半径和体积

题目描述:

输入球的中心点和球上某一点的坐标,计算球的半径和体积

输入:
球的中心点和球上某一点的坐标,以如下形式输入:x0 y0 z0 x1 y1 z1
输出:
输入可能有多组,对于每组输入,输出球的半径和体积,并且结果保留三位小数
样例输入:
0 0 0 1 1 1 
样例输出:
1.732 21.766
提示:

为避免精度问题,PI值请使用arccos(-1)。

#include
#include
#include
int main()
{
        double  r,x0,y0,z0,x1,y1,z1;
  while(scanf("%lf%lf%lf%lf%lf%lf",&x0,&y0,&z0,&x1,&y1,&z1)!=-1)
    {
 
       r=sqrt(pow((x0-x1),2)+pow((y0-y1),2)+pow((z0-z1),2));
       printf("%.3lf %.3lf\n",r,pow(r,3)*4*acos(-1)/3);
     }
   return 0;
}
/**************************************************************
    Problem: 1068
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1108 kb
****************************************************************/


题目1069:查找学生信息


题目描述:

 输入N个学生的信息,然后进行查询。

输入:

 输入的第一行为N,即学生的个数(N<=1000)

接下来的N行包括N个学生的信息,信息格式如下:
01 李江 男 21
02 刘唐 男 23
03 张军 男 19
04 王娜 女 19
然后输入一个M(M<=10000),接下来会有M行,代表M次查询,每行输入一个学号,格式如下:
02
03
01
04
输出:

 输出M行,每行包括一个对应于查询的学生的信息。

如果没有对应的学生信息,则输出“No Answer!”
样例输入:
4
01 李江 男 21
02 刘唐 男 23
03 张军 男 19
04 王娜 女 19
5
02
03
01
04
03
样例输出:
02 刘唐 男 23
03 张军 男 19
01 李江 男 21
04 王娜 女 19
03 张军 男 19
#include "string"
#include "vector"
#include "stack"
#include "iostream"
 
 
using namespace std;
 
typedef struct _StuInfo
{
    string num;
    string name;
    string sex;
    int age;
}StuInfo;
 
int main(void)
{
    int N = 0, M = 0;
    while (cin>>N)//有N位同学
    {
        vector stu(N);
        for (int i = 0; i < N;i++)//输入N个同学的具体信息
        {
            cin >> stu[i].num >> stu[i].name >> stu[i].sex >> stu[i].age;
        }
        cin >> M;//M次查询
        for (int i = 0; i < M;i++)//依次查询并输出结果
        {
            string num;
            cin >> num;//输入学号
            int j = 0;
            for (; j < N;j++)
            {
                if (stu[j].num == num)//找到这位学生
                    break;
            }
            if (j < N)
                cout << stu[j].num << " " << stu[j].name << " " << stu[j].sex << " " << stu[j].age << endl;
            else
                cout << "No Answer!" << endl;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1069
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:140 ms
    Memory:1520 kb
****************************************************************/




题目1070:今年的第几天?

题目描述:

输入年、月、日,计算该天是本年的第几天。

输入:

包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。

输出:
输入可能有多组测试数据,对于每一组测试数据,
输出一个整数,代表Input中的年、月、日对应本年的第几天。
样例输入:
1990 9 20
2000 5 1
样例输出:
263
122
#include "iostream"  
 
using namespace std;
 
int leap(int a)          //自定义函数leap用来指定年份是否为闰年
{
    if (a % 4 == 0 && a % 100 != 0 || a % 400 == 0)//闰年判定条件
        return 1;                //是闰年返回1
    else
        return 0;         //不是闰年返回0
}
 
int number(int year, int m, int d) //自定义函数number计算输入日期为该年第几天
{
    int sum = 0, i;
    //数组a存放平年每月的天数
    int a[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int b[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };      //数组b存放闰年每月的天数
    if (leap(year) == 1)           //判断是否为闰年
    {
        for (i = 0; i < m - 1; i++)
            sum += b[i];   //是闰年,累加数组b前m-1个月份天数
    }
    else
    {
        for (i = 0; i < m - 1; i++)
            sum += a[i]; //不是闰年,累加数组a钱m-1个月份天数
    }
    sum += d;                                       //将前面累加的结果加上日期,求出总天数
    return sum;                                     //将计算的天数返回
}
 
int main()
{
    int year, month, day, n;           //定义变量为基本整型
    while (cin >> year >> month >> day)
    {
        if (year > 3000 || year<1 || month>12 || month<1 || day>31 || day < 1)
            break;
         
        n = number(year, month, day);            //调用函数number
        cout << n << endl;
    }
     
    return 0;
}
/**************************************************************
    Problem: 1070
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:170 ms
    Memory:1520 kb
****************************************************************/


题目1072:不同的面值组合

题目描述:

某人有8角的邮票5张,1元的邮票4张,1元8角的邮票6张,用这些邮票中的一张或若干张可以得到多少种不同的邮资?

输入:

题目没有任何输入

输出:

按题目的要求输出可以得到的不同邮资的数目

样例输入:
 
     
样例输出:
#include "vector"
#include "iostream"
#include 
 
using namespace std;
 
int main()
{
    int i, j, k, cnt = 0, tmp = 0, s = 0;
    vector sum;
    for (i = 0; i <= 5; i++)
        for (j = 0; j <= 4; j++)
            for (k = 0; k <= 6; k++)
                sum.push_back(i * 8 + j * 10 + k * 18);
     
    sort(sum.begin(), sum.end());
 
    for (i = 1; i < 6*5*7; i++)
    {
        if (sum[i] != sum[tmp])//tmp位置的所有元素互不同
        {
            cnt++;
            tmp = i;
        }
    }
    cout << cnt << endl;
    return 0;
}
/**************************************************************
    Problem: 1072
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1516 kb
****************************************************************/



题目1073:杨辉三角形

题目描述:

输入n值,使用递归函数,求杨辉三角形中各个位置上的值。

输入:

一个大于等于2的整型数n

输出:

题目可能有多组不同的测试数据,对于每组输入数据,
按题目的要求输出相应输入n的杨辉三角形。

样例输入:
6
样例输出:
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
#include "iostream"
 
using namespace std;
int s[100][100] = { 0 };//存储杨辉数组
int getYanghui(int n, int i)//计算并获取杨辉行(具有n个数时)第i个数据
{
    if (i == 1 || n == 2 || n == i)
        return 1;
    else if (s[n][i] != 0)
        return s[n][i];
    else   return getYanghui(n - 1, i - 1) + getYanghui(n - 1, i);
}
int main()
{
    int n;
    while (cin >> n)
    {
        for (int i = 2; i <= n; i++)//当前杨辉行的数字个数
        {
            cout<<"1 ";
            for (int j = 2; j < i; j++)//杨辉行个数为i时需要计算i-2个杨辉数
            {
                cout << getYanghui(i, j) << " ";
                s[i][j] = getYanghui(i, j);
            }
            cout <<"1"<< endl;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1073
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1556 kb
****************************************************************/

题目1074:对称平方数

题目描述:
打印所有不超过n(n<256)的,其平方具有对称性质的数。
如11*11=121
输入:

无任何输入数据

输出:
输出具有题目要求的性质的数。如果输出数据不止一组,各组数据之间以回车隔开。
样例输入:
 
    
样例输出:
#include "iostream"  
 
using namespace std;
int main()
{
    int i, m, n;
    for (i = 0; i <= 256; i++)
    {
        n = i*i; m = 0;
        while (n)
        {
            m = m * 10 + n % 10;//122=1*100+2*10+2,但!=2*100+2*10+1,但是121可以
            n = n / 10;
        }
        if (m == i*i)
            cout<

题目1075:斐波那契数列


题目描述:

编写一个求斐波那契数列的递归函数,输入n值,使用该递归函数,输出如样例输出的斐波那契数列。

输入:

一个整型数n

输出:

题目可能有多组不同的测试数据,对于每组输入数据,
按题目的要求输出相应的斐波那契图形。

样例输入:
6
样例输出:
0
0 1 1
0 1 1 2 3
0 1 1 2 3 5 8
0 1 1 2 3 5 8 13 21
0 1 1 2 3 5 8 13 21 34 55
C++实现如下:
#include "vector"
#include "iostream"
using namespace std;
int main(void)
{
    int n=0;
    vector vec(100,0);
    while (cin>>n)
    {
        cout << 0 << endl;//第一行
        for (int i = 1; i < n;i++)//第二行到指定行的控制
        {
            cout << 0 << " " << 1;//从第二行起每一行都有0 ,1
            for (int j = 2; j < 2 * (i + 1)-1;j++)//输出每一行除去0,1后的接下来的数据
            {
                vec[0] = 0;
                vec[1] = 1;
                vec[j] = vec[j - 1] + vec[j - 2];
                cout << " " <


题目1076:N的阶乘

题目描述:

 输入一个正整数N,输出N的阶乘。

输入:

正整数N(0<=N<=1000)

输出:

 输入可能包括多组数据,对于每一组输入数据,输出N的阶乘

样例输入:
4
5
15
样例输出:
24
120
1307674368000
C++程序实现如下:

#include "iostream"
#include "string"
#include 
#include 
using namespace std;
int res[10010];
int main()
{
    int n;
    while (cin>>n)
    {
        int i, j;
        memset(res, 0, sizeof(res));//全部置零
        res[0] = 1;//f(0)
        res[1] = 1;//f(1)
 
        for (i = 2; i <= n; i++)
        {
            for (j = 1; j <= res[0]; j++)
            {
                res[j] = res[j] * i;
            }
            for (j = 1; j <= res[0]; j++)
            {
                if (res[j] >= 10)
                {
                    res[j + 1] += res[j] / 10;
                    res[j] %= 10;
                    if (j == res[0])
                    {
                        res[0]++;
                    }
                }
            }
        }
 
        for (i = res[0]; i >= 1; i--)
        {
            cout << res[i];
        }
        cout << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1076
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:2010 ms
    Memory:1556 kb
****************************************************************/


题目1077:最大序列和

题目描述:

给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”。
对于S的所有非空连续子序列T,求最大的序列和。
变量条件:N为正整数,N≤1000000,结果序列和在范围(-2^63,2^63-1)以内。
 

输入:

第一行为一个正整数N,第二行为N个整数,表示序列中的数。

输出:

输入可能包括多组数据,对于每一组输入数据,
仅输出一个数,表示最大序列和。


方法:

经典基础动态规划例子

寻找转移式子

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

6
1 -2 3 4 -10 6

4
-3 -1 -2 -5
样例输出:
9
7
-1
C++程序实现如下:


#include "iostream"  
#include "vector"
using namespace std;

long long int getMax(long long int a, long long int b)
{
	if (a > b)
		return a;
	else
		return b;
}

long long int getMaxSum(vector &vec)
{
	vector< long long int> tempSum(vec.size(), 0);//tempSum[i]只与vec[i]有关,非连续,非最大,非子段和....
	tempSum[0] = vec[0];
	vector  maxSum(vec.size(), 0);//maxSum[i]表示a[0]到a[i]的最大子段和值
	maxSum[0]= vec[0];//当只有一元素时的最大连续子段和
	long i = 1;
	for (; i < vec.size(); i++)
	{//状态转移//如果tempSum[i - 1] + vec[i]小,说明tempsum起副作用了(小于0了),重新以当前元素vec[i]开始累加
		tempSum[i] = getMax(tempSum[i - 1] + vec[i], vec[i]);
		maxSum[i] = getMax(maxSum[i - 1], tempSum[i]);//更新a[0]到a[i]的最大子段和值
		//maxSum[i] = getMax(maxSum[i - 1], getMax(tempSum[i - 1] + vec[i], vec[i]));
	}
	return maxSum[i-1];
}


int main()
{
	long long int  n = 0;
	while (cin >> n)
	{
		vector< long long int> ivec(n, 0);
		for (long i = 0; i < n; i++)
			cin >> ivec[i];
		long long int  maxSum = getMaxSum(ivec);
		cout << maxSum << endl;
	}
	return 0;
}


题目1078:二叉树遍历

题目描述:

二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。

输入:

两个字符串,其长度n均小于等于26。
第一行为前序遍历,第二行为中序遍历。
二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。

输出:

输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。

方法:

1,不使用建树的方法;

假设前序遍历为 adbgcefh, 中序遍历为 dgbaechf
前序遍历是先访问根节点,然后再访问子树的,而中序遍历则先访问左子树再访问根节点
那么把前序的 a 取出来,然后查找 a 在中序遍历中的位置就得到 dgb a echf
那么我们就知道 dgb 一定是二叉树的左子树,而 echf 是右子树, 显然在前序中相应的 dbg 是左子树 cefh 是右子树 

然后继续根据这种规则根据前序遍历的“左子树”和后序遍历的“左子树”,推导出真正的左子树(未建树,并未真正这样操作),当对左子树遍历到只有一个节点时(这时前序遍历的与后序遍历的左子树是相同的哈),此时就可以打印了。然后就变成了一个递归的过程。

2,建树,然后后序遍历


样例输入:
ABC
BAC
FDXEAG
XDEFAG
样例输出:
BCA
XEDGAF
#include "string"
#include "iostream"    
 
using namespace std;
 
bool PreMidToBack(const string &prestr, const string &midstr)
{
    if (prestr.size() == 0)
        return false;
    if (prestr.size() == 1)
    {
        cout << prestr;
        return true;
    }
 
    //在中序遍历中找到前序遍历的第一个节点的位置(就是当前根节点)  
    int k = midstr.find(prestr[0]);//寻找字符c在字符串str中第一次出现的位置
    //分别在前序和后序遍历中寻找原二叉树的左子树
    string preLeft = prestr.substr(1, k);
    string midLeft = midstr.substr(0, k);
    PreMidToBack(preLeft, midLeft); //后序遍历:1.先后序遍历完左子树
 
    //同理寻找右子树
    string preRight = prestr.substr(k + 1, prestr.size() - k - 1);
    string midRight = midstr.substr(k + 1, midstr.size() - k - 1);
    PreMidToBack(preRight, midRight);//后序遍历:2.再后序遍历完右子树
 
    //变成后序遍历要最后输出节点的值  
    cout << prestr[0];//后序遍历:3.最后访问根节点(注意:这个是整个二叉树的根)
}
 
int main()
{
    string preStr, midStr;
    while (cin >> preStr >> midStr)
    {
        PreMidToBack(preStr, midStr);
        cout << endl;
    }
}
/**************************************************************
    Problem: 1078
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/

方法2:建二叉树的方法

#include 
#include "string" 
 
using namespace std;
 
//节点定义
class BSTNode
{
public:
    BSTNode(int ndata)//有参数的构造
    {//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面  
        pRight = NULL;
        pLeft = NULL;
        value = ndata;
    }
    friend class LinkBST;//允许链表类随意访问节点数据
 
private:
    char value;
    BSTNode *pRight;
    BSTNode *pLeft;
};
 
// 带头结点的二叉树定义 
class LinkBST
{
public:
    LinkBST(){}
    ~LinkBST(){}
    //后序遍历
    void postOrder(BSTNode *pNode);
    //重建二叉树
    void ReBuildBST(const string &preStr, const string &midStr, BSTNode *&proot);
 
private:
};
 
//Tips:
//int *a;int * &p = a;
//很容易理解,把 int * 看成一个类型,a就是一个整型指针,p 是a的别名,那么a与p就完全等同了
void LinkBST::ReBuildBST(const string &preStr, const string &midStr, BSTNode *&proot)
{//注意:proot是引用,要不然函数返回会对proot的内容进行撤销
    if (preStr.size() == 0)
        return;
 
    proot = new BSTNode(0);
    proot->value = preStr[0];//prestr[0]肯定是当前二叉树的根
    proot->pLeft = NULL;
    proot->pRight = NULL;
 
    if (preStr.size() == 1)
        return;
 
    int k = midStr.find(preStr[0]);//找到字符出现的第一个位置
    string preLeft = preStr.substr(1, k);
    string midLeft = midStr.substr(0, k);
    ReBuildBST(preLeft, midLeft, proot->pLeft);
 
    string preRight = preStr.substr(k + 1, preStr.size() - k - 1);
    string midRight = midStr.substr(k + 1, midStr.size() - k - 1);
    ReBuildBST(preRight, midRight, proot->pRight);
}
 
void LinkBST::postOrder(BSTNode *pNode)
{
    if (pNode != NULL){
        postOrder(pNode->pLeft);
        postOrder(pNode->pRight);
        cout << pNode->value;
    }
}
 
int main()
{
    string preStr, midStr;
    while (cin >> preStr >> midStr)
    {
        BSTNode *pRoot = NULL;
        LinkBST bst;
        bst.ReBuildBST(preStr, midStr, pRoot);
        bst.postOrder(pRoot);
        cout << endl;
    }
}
/**************************************************************
    Problem: 1078
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/



题目1079:手机键盘

题目描述:
按照手机键盘输入字母的方式,计算所花费的时间
如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次。
如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,kz需要按6下
如果连续两字符在同一个按键上,则两个按键之间需要等一段时间,如ac,在按了a之后,需要等一会儿才能按c。
现在假设每按一次需要花费一个时间段,等待时间需要花费两个时间段。
现在给出一串字符,需要计算出它所需要花费的时间。
输入:

一个长度不大于100的字符串,其中只有手机按键上有的小写字母

输出:
输入可能包括多组数据,对于每组数据,输出按出Input所给字符串所需要的时间
样例输入:
bob
www
样例输出:
7
7
#include "string"
#include
#include 
 
using namespace std;
 
const string baseKeyPos = "11122233344455566667778888";//字母所在按键的位置
 
int cal(string s) 
{
    int len = s.length();
    int ans = 0, prePos = 0, curPos;
    for (int i = 0; i> s) 
        cout << cal(s) << endl;
    return 0;
}
/**************************************************************
    Problem: 1079
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:20 ms
    Memory:1520 kb
****************************************************************/


题目1080:进制转换

题目描述:

将M进制的数X转换为N进制的数输出。

输入:

输入的第一行包括两个整数:M和N(2<=M,N<=36)。
下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。

输出:

输出X的N进制表示的数。

样例输入:
16 10
F
样例输出:
15
提示:

输入时字母部分为大写,输出时为小写,并且有大数据。


#include "string"
#include "vector"
 
#include 
using namespace std;
 
void convertHex(string &strk, int M, int N)
{
    int i, k = 0;
    bool flag = false;
    vector a(1000, 0);
    vector b(1000, 0);
    for (i = 0; i < strk.size(); i++)//转换成数放在数组中,注意高位在第一位
    {
        if (strk[i] <= '9' && strk[i] >= '0')//如果是数字
            a[i] = strk[i] - '0';
        else
            a[i] = strk[i] - 'A' + 10;//如果是大写字母
    }
    while (true)//循环取余数
    {
        for (i = 0; i < strk.size() - 1; i++)
        {
            if (a[i] != 0)
            {
                a[i + 1] += a[i] % N*M;//每位余数加到下一位
                a[i] /= N;
            }
        }
        b[k++] = a[i] % N;//最后一位余数
        a[i] /= N;
        flag = 0;
        for (i = 0; i < strk.size(); i++)//是否已除完
        {
            if (a[i] != 0)
                flag = 1;
        }
             
        if (!flag)
            break;
    }
 
    for (i = k - 1; i >= 0; i--)//余数倒序输出即可
    {
        if (b[i] >= 10)
            cout << char('a' + b[i] - 10);
        else
            cout << char('0' + b[i]);
    }
    cout << endl;
}
 
int main()
{
    int M = 0, N = 0;
    string strk;
    while (cin>>M>>N)
    {
        if (M<2 || M>36 || N<2 || N>36)
            break;
        cin >> strk;
        convertHex(strk, M, N);
    }
    return 0;
}
 
/**************************************************************
    Problem: 1080
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:60 ms
    Memory:1520 kb
****************************************************************/


题目1081:递推数列

题目描述:

给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q。这里n >= 2。 求第k个数对10000的模。

输入:

输入包括5个整数:a0、a1、p、q、k。

输出:

第k个数a(k)对10000的模。

样例输入:
20 1 1 14 5
样例输出:
8359
#include "vector"
#include "string"
#include "iostream"
using namespace std;
 
 
int getRecursiveSequence(const vector &vec);
 
int main()
{
    while (true)
    {
        vector vec(5, 0);
        for (int i = 0; i < 5;i++)
            cin >> vec[i];
        cout << getRecursiveSequence(vec) << endl;
    }
    return 0;
}
 
int getRecursiveSequence(const vector &vec)
{
    int a0 = vec[0];
    int a1 = vec[1];
    int an = 0;
    if (vec[4] == 0)
        return a0;
    if (vec[4] == 1)
        return a1;
 
    for (int i = 2; i <= vec[4];i++)
    {
        an = (vec[2] * a1 + vec[3] * a0)%10000;
        a0 = a1;
        a1 = an;
    }
    return an;
}
/**************************************************************
    Problem: 1081
    User: EbowTang
    Language: C++
    Result: Time Limit Exceed
****************************************************************/

题目1083:特殊乘法

题目描述:

写个算法,对2个小于1000000000的输入,求结果。

特殊乘法举例:123 * 45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5

输入:

 两个小于1000000000的数

输出:

 输入可能有多组数据,对于每一组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

样例输入:
123 45
样例输出:
54

#include 
#include 
using namespace std;
 
// 返回数字n的各个位数之和,如123,返回6
int Func(int n)
{
        int ans = 0;
        while (n != 0)
        {
                ans += n % 10;
                n /= 10;
        }
        return ans;
}
 
int main()
{
        int a, b;
        while (scanf("%d%d", &a, &b) != EOF)
        {
                int ans = Func(a) * Func(b);
                printf("%d\n", ans);
        }
        return 0;
}
/**************************************************************
    Problem: 1083
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1520 kb
****************************************************************/

题目1084:整数拆分

题目描述:

一个整数总可以拆分为2的幂的和,例如:
7=1+2+4
7=1+2+2+2
7=1+1+1+4
7=1+1+1+2+2
7=1+1+1+1+1+2
7=1+1+1+1+1+1+1
总共有六种不同的拆分方式。
再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。
用f(n)表示n的不同拆分的种数,例如f(7)=6.
要求编写程序,读入n(不超过1000000),输出f(n)%1000000000。

输入:

每组输入包括一个整数:N(1<=N<=1000000)。

输出:

对于每组数据,输出f(n)%1000000000。

样例输入:
7
样例输出:
6

#include 
using namespace std;
int f[1000001] = { 0 };//增加一个
int fun(int n); //求解并返回 f(n)
int main()
{
    int n;
    while (cin >> n)
        cout << fun(n) << endl;
    return 0;
}
 
int fun(int n)  //求解并返回 f(n)
{
    f[0] = 1;
    f[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (i % 2 ) //i能被2整除的话余数是0,反之不为0,即为真
            f[i] = f[i - 1];
        else
            f[i] = (f[i / 2] + f[i - 1]) % 1000000000;
    }
    return f[n];
}
/**************************************************************
    Problem: 1084
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:140 ms
    Memory:5424 kb
****************************************************************/



题目1087:约数的个数

题目描述:

输入n个整数,依次输出每个数的约数的个数

输入:

输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。

输出:

可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。

样例输入:
5
1 3 4 6 12
样例输出:
1
2
3
4
6


#include   
#include   
#include "vector"
#include "string"
#include "algorithm"
#include 
#include "stack"
#include  
 
using namespace std;
 
int getDivisor(int key);
int main()
{
    int n = 0;
    while (scanf("%d", &n) != EOF)
    {
        vector vec(n, 0);
        //接受输入
        for (int i = 0; i < n; i++)
            scanf("%d", &vec[i]);
        //获取每一个数的约数个数
        for (int i = 0; i < n; i++)
            cout << getDivisor(vec[i]) << endl;
    }
    return 0;
}
 
//计算数key的约数
//方法:求key的约数个数的方法:将key开方得a,
//判断a之前属于key的约数个数count。
//若key为某个整数的平方,则key约数个数为2*count-1,否则为2*count
//参考:
//http://baike.haosou.com/doc/5806281-6019081.html
int getDivisor(int key)
{
    /*
    int count = 1;//key本身算一个
    for (int i = 1; i <= sqrt(key); i++)
    {//朴素的寻找方法
        if (key % i == 0)
            count++;
    }
    return count;
    */
    int count = 0;
    int a = sqrt(key);
    for (int i = 1; i <= a; i++)
    {
        if (key % i == 0)
            count++;
    }
    if (a*a != key) 
        count = 2 * count;
    else
        count = 2 * count-1;
    return count;
}
/**************************************************************
    Problem: 1087
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:150 ms
    Memory:1532 kb
****************************************************************/



题目1089:数字反转

题目描述:

    12翻一下是21,34翻一下是43,12+34是46,46翻一下是64,现在又任意两个正整数,问他们两个数反转的和是否等于两个数的和的反转。

输入:

    第一行一个正整数表示测试数据的个数n。
    只有n行,每行两个正整数a和b(0

输出:

    如果满足题目的要求输出a+b的值,否则输出NO。

样例输入:
2
12 34
99 1
样例输出:
46
NO
#include 
using namespace std;
int main()
{
 
    int n, a, b, sum, tempa, tempb;
    while (cin>>n)
    {
        for (int i = 0; i < n; i++)
        {
            int ra = 0;//a的翻转  
            int rb = 0;//b的翻转  
            int rsum = 0;//a+b和的翻转  
     
            cin >> a >> b;
            tempa = a;
            tempb = b;
                 
            //a的翻转  
            while (tempa)
            {//152的反转为例,2将会是最高位,所以累乘,每次取低位
                ra = ra * 10 + tempa % 10;
                tempa = tempa / 10;
            }
            //b的翻转  
            while (tempb)
            {
                rb = rb * 10 + tempb % 10;
                tempb = tempb / 10;
            }
 
            sum = a + b;
            //a+b和的翻转  
            while (sum)
            {
                rsum = rsum * 10 + sum % 10;
                sum = sum / 10;
            }
            //两个数反转的和是否等于两个数的和的反转。  
            if (ra + rb == rsum)
                cout << a + b;
            else
                cout <<"NO"<< endl;;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1089
    User: EbowTang
    Language: C++
    Result: Wrong Answer
****************************************************************/

题目1092:Fibonacci

题目描述:

    The Fibonacci Numbers{0,1,1,2,3,5,8,13,21,34,55...} are defined by the recurrence: 
    F0=0 F1=1 Fn=Fn-1+Fn-2,n>=2 
    Write a program to calculate the Fibonacci Numbers.

输入:

    Each case contains a number n and you are expected to calculate Fn.(0<=n<=30) 。

输出:

   For each case, print a number Fn on a separate line,which means the nth Fibonacci Number.

样例输入:
1
样例输出:
1
#include 
using namespace std;
int Fibonacci(int n);
int main()
{
    int n = 0;
    while (cin >> n)
    {
        int ans = 0;
        ans = Fibonacci(n);
        cout << ans<


题目1094:String Matching

题目描述:

    Finding all occurrences of a pattern in a text is a problem that arises frequently in text-editing programs. 
    Typically,the text is a document being edited,and the pattern searched for is a particular word supplied by the user.  
    We assume that the text is an array T[1..n] of length n and that the pattern is an array P[1..m] of length m<=n.We further assume that the elements of P and  T are all alphabets(∑={a,b...,z}).The character arrays P and T are often called strings of characters.  
    We say that pattern P occurs with shift s in the text T if 0<=s<=n and T[s+1..s+m] = P[1..m](that is if T[s+j]=P[j],for 1<=j<=m).  
    If P occurs with shift s in T,then we call s a valid shift;otherwise,we calls a invalid shift. 
    Your task is to calculate the number of vald shifts for the given text T and p attern P.

输入:

   For each case, there are two strings T and P on a line,separated by a single space.You may assume both the length of T and P will not exceed 10^6. 

输出:

    You should output a number on a separate line,which indicates the number of valid shifts for the given text T and pattern P.

样例输入:
abababab abab
样例输出:
3
#include //小数点精确
#include   
#include   
#include "vector"
#include "string"
#include "algorithm"
#include 
#include "stack"
#include "math.h"  
 
using namespace std;
 
//计算模式P的部分匹配值,保存在next数组中    
void MakeNext(const string &P, vector &next)
{
    int q, k;//k记录所有前缀的对称值    
    int m = P.size();//模式字符串的长度    
    next[0] = 0;//首字符的对称值肯定为0    
    for (q = 1, k = 0; q < m; ++q)//计算每一个位置的对称值    
    {
        //k总是用来记录上一个前缀的最大对称值    
        while (k > 0 && P[q] != P[k])
            k = next[k - 1];//k将循环递减,值得注意的是next[k] &next)
{
    int n = 0, m = 0, count = 0;
    n = T.size();
    m = P.size();
    MakeNext(P, next);
    for (int i = 0, q = 0; i < n; ++i)
    {
        while (q > 0 && P[q] != T[i])
            q = next[q - 1];
        if (P[q] == T[i])
            q++;
        if (q == m)
        {
            q = next[q - 1];//寻找下一个匹配  
            count++;
        }
    }
    return count;
}
 
int main()
{
    string T;//文本  
    string P;//待搜索字符串 
    vector next(200, 0);//保存待搜索字符串的部分匹配表(所有前缀函数的对称值)  
    while (cin >> T >> P)
    {//本题为kmp算法的简单应用
        cout << KmpMatch(T, P, next) << endl;
    }
         
    return 0;
}
/**************************************************************
    Problem: 1094
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:160 ms
    Memory:3052 kb
****************************************************************/



题目1096:日期差值

题目描述:

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天

输入:

有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD

输出:

每组数据输出一行,即日期差值

样例输入:
20110412
20110422
样例输出:
11
#include "string"
#include "vector"
#include "stack"
#include "math.h"
#include 
#include "iostream"    
 
using namespace std;
 
//数组a存放平年每月的天数  
int a[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int b[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };      //数组b存放闰年每月的天数 
//能被4整除且又能不能被100整除 是闰年
//能直接被400整除也是闰年
//闰年:   
//1.为了弥补人为的年份规定与地球实际绕日公转的时间差,
//2.而人为把时间差补上了的年份,该年即为闰年.
//增加闰日的原因
//现时的公历以回归年为“年”的计算基础,而一个回归年大约等于365.24220日。
//因为在平年公历只计算365日,结果四年后便会累积0.24220×4 = 0.9688日,
//大约等于一日,所以便逢四年增加一日闰日以抵销这0.9688日。
int leap(int a)          //自定义函数leap用来指定年份是否为闰年  
{
    if (a % 4 == 0 && a % 100 != 0 || a % 400 == 0)//闰年判定条件  
        return 366;                //是闰年返回1  
    else
        return 365;         //不是闰年返回0  
}
 
int number(int year, int m, int d) //自定义函数number计算输入日期为该年第几天  
{
    int sum = 0, i; 
    if (leap(year) == 366)           //判断是否为闰年  
    {
        for (i = 0; i < m - 1; i++)
            sum += b[i];   //是闰年,累加数组b前m-1个月份天数  
    }
    else
    {
        for (i = 0; i < m - 1; i++)
            sum += a[i]; //不是闰年,累加数组a钱m-1个月份天数  
    }
    sum += d;                                       //将前面累加的结果加上日期,求出总天数  
    return sum;                                     //将计算的天数返回  
}
 
void getymd(string &str,int &y,int &m,int &d)
{
    for (int i = 0; i < 4;i++)
    {
        y = y * 10;
        y = y + str[i] - '0';
    }
 
    for (int i = 4; i < 6; i++)
    {
        m = m * 10;
        m = m + str[i] - '0';
    }
 
    for (int i = 6; i < 8; i++)
    {
        d = d * 10;
        d = d + str[i] - '0';
    }
}
int main()
{
     
    while (true)
    {
        int year1 = 0, month1 = 0, day1 = 0, n1=0;           //定义变量为基本整型 
        int year2 = 0, month2 = 0, day2 = 0, n2=0;
        string str;
        cin >> str;
        getymd(str, year1, month1, day1);
        if (month1 > 12 || day1 > 31)
            exit(1);
        n1 = number(year1, month1, day1);            //调用函数number得到第一年的  
        str.erase();
        cin >> str;
        getymd(str, year2, month2, day2);
        if (month2 > 12 || day2 > 31)
            exit(1);
        n2 = number(year2, month2, day2);            //调用函数number  
 
        int sumyear = 0;
        if (year2>year1)
        {
            while (year2 > year1)
                sumyear = sumyear + leap(year1++);
            cout << abs(sumyear - n1 + n2)+1 << endl;
        }
        else
        {
            while (year1 > year2)
                sumyear = sumyear + leap(year2++);
            cout << abs(sumyear - n2 + n1) +1<< endl;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1096
    User: EbowTang
    Language: C++
    Result: Output Limit Exceed
****************************************************************/

题目1097:取中值

题目描述:

     存在两组数组,和4个数字a,b,c,d,要求做如下操作,将第一个数组第a个数到第b个数,第二个数组的第c个数到第d个数放到一个数组中,求出合并后数组的中间值,如果有两个中间值,取下标较小的那个。

输入:

    第一行一个整数t表示有t个测试数据
    第二行两个整数,表示两个数组的长度,
    接下来两行表示两个数字的值,

    最后一行有四个整数a,b,c,d。

    数组长度不会超过1000000。

输出:

    每行一个整数,对应合并数组的下标在中间的那个值。

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


#include "vector"
#include "math.h"
#include
#include 
 
using namespace std;
 
int main() 
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int aLen, bLen;
        int a, b, c, d;
        int npos = 0;
        cin >> aLen >> bLen;
        vector avec(aLen), bvec(bLen);
        //获取数据
        for (int j = 0; j> avec[j];
        for (int j = 0; j> bvec[j];
         
        cin >> a >> b >> c >> d;
        vector mergevec(b+d-a-c+2);
 
        //合并数据
        for (int j = a; j <= b; j++)
            mergevec[npos++] = avec[j - 1];
        for (int j = c; j <= d; j++)
            mergevec[npos++] = bvec[j - 1];
             
        cout << mergevec[(npos - 1) / 2] << endl;
    }
    return 0;
}
/**************************************************************
    Problem: 1097
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:110 ms
    Memory:1720 kb
****************************************************************/


题目1098:字母统计

题目描述:

输入一行字符串,计算其中A-Z大写字母出现的次数

输入:

案例可能有多组,每个案例输入为一行字符串。

输出:

对每个案例按A-Z的顺序输出其中大写字母出现的次数。

样例输入:
DFJEIWFNQLEF0395823048+_+JDLSFJDLSJFKK
样例输出:
A:0
B:0
C:0
D:3
E:2
F:5
G:0
H:0
I:1
J:4
K:2
L:3
M:0
N:1
O:0
P:0
Q:1
R:0
S:2
T:0
U:0
V:0
W:1
X:0
Y:0
Z:0
C++程序实现如下:
#include 
#include "string"
#include "vector"
using namespace std;
 
bool countChar(const string &src, vector &countTime);
int main()
{
    string str;
    while (cin>>str)
    {
        if (str.length() > 1000 || str.length() < 1)
            break;
        vector countTime(26, 0);
        countChar(str,countTime);
        char a = 'A';
        for (int i = 0; i < 26;i++)
        {
            cout << a << ":" << countTime[i] << endl;
            a++;
        }
        str.erase();
    }
    return 0;
}
 
bool countChar(const string &src, vector &countTime)
{
    if (src.length() == 0)
        return false;
 
    for (unsigned int i = 0; i < src.size();i++)
    {
        if (src[i] >= 'A' && src[i] <= 'Z')
        {
            int pos = src[i] - 'A';
            countTime[pos]++;
        }
    }
    return true;
}
/**************************************************************
    Problem: 1098
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/

题目1099:后缀子串排序


题目描述:

对于一个字符串,将其后缀子串进行排序,例如grain
其子串有:
grain 
rain 
ain 
in 
n

然后对各子串按字典顺序排序,即: 
ain,grain,in,n,rain

输入:

每个案例为一行字符串。

输出:

将子串排序输出

样例输入:
grain
样例输出:
ain
grain
in
n
rain

#include "string"
#include 
 
using namespace std;
 
int main() 
{
    string str;
    while (cin>>str)
    {
        int len = str.size();
        int pos = 0;
        int *visited=new int[len];
         
        int i = 0;
        while (i stepsub)
                {
                    minsub = stepsub;
                    pos = j;
                }
            }
            visited[pos] = 1;
            cout << minsub << endl;
            i++;
        }   
    }
    return 0;
}
/**************************************************************
    Problem: 1099
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/






你可能感兴趣的:(九度OJ解题集,九度OJ解题报告)