/imgs/avatar.jpg

1015 德才论

宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”

现给出一批考生的德才分数,请根据司马光的理论给出录取排名。

输入格式:

输入第一行给出 3 个正整数,分别为:N(≤105),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到优先录取线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。

随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。

输出格式:

输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。

输入样例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

输出样例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

思路

首先对第一种情况进行判断,当不满足时再对第二种情况进行判断

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//坏情况
bool cmp(inf a, inf b)
{
    if (a.flag == b.flag)
    {
        int sum1, sum2;
        sum1 = a.virtue + a.talent;
        sum2 = b.virtue + b.virtue;
        if (sum1 == sum2)
        {
            if (a.virtue == b.virtue)  return strcmp(a.num, b.num) < 0;
            return a.virtue > b.virtue;
        }
        return sum1 > sum2;
    }
    return a.flag > b.flag;

}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

/*
    使用一个结构体来存储考生的信息,使用flag来存储考生的分类,
    当对学生进行排序的时候,首先判断按照分类进行排序,同一分类
    里面按照的是总分进行排序。
*/

struct inf
{
    char num[20];
    int virtue;
    int talent;
    int flag;
};

bool cmp(inf a, inf b)
{
    int sum1 = a.virtue + a.talent, sum2 = b.virtue + b.talent;
    if (a.flag != b.flag)  return a.flag < b.flag;
    else if (sum1 != sum2)  return sum1 > sum2;
    else if (a.virtue != b.virtue)  return a.virtue > b.virtue;
    return strcmp(a.num, b.num) < 0;
}

int main()
{
    int n, l, h;
    inf *data = new inf[100005];
    scanf("%d%d%d", &n, &l, &h);
    int count = n;
    for (int i = 0; i < n; i++)
    {
        scanf("%s%d%d", data[i].num, &data[i].virtue, &data[i].talent);

        if (data[i].virtue < l || data[i].talent < l)
        {
            data[i].flag = 0;
            count--;
        }
        else if (data[i].virtue >= h && data[i].talent >= h)
        {
            data[i].flag = 1;
        }
        else if (data[i].virtue >= h && data[i].talent < h)
        {
            data[i].flag = 2;
        }
        else if (data[i].virtue < h && data[i].talent < h && data[i].virtue >= data[i].talent)
        {
            data[i].flag = 3;
        }
        else
        {
            data[i].flag = 4;
        }
    }
        sort(data, data + n, cmp);
        printf("%d\n", count);
        for (int i = 0; i < n; i++)
        {
            if (!data[i].flag)
                continue;
            printf("%s %d %d", data[i].num, data[i].virtue, data[i].talent);
            if (i != n - 1)
                printf("\n");
        }
        delete[] data;
        return 0;
    }

1082 Read Number in Chinese

Given an integer with no more than 9 digits, you are supposed to read it in the traditional Chinese way. Output Fu first if it is negative. For example, -123456789 is read as Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu. Note: zero (ling) must be handled correctly according to the Chinese tradition. For example, 100800 is yi Shi Wan ling ba Bai.

Input Specification:

Each input file contains one test case, which gives an integer with no more than 9 digits.

Output Specification:

For each test case, print in a line the Chinese way of reading the number. The characters are separated by a space and there must be no extra space at the end of the line.

Sample Input 1:

1
-123456789

Sample Output 1:

1
Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu

Sample Input 2:

1
100800

Sample Output 2:

1
yi Shi Wan ling ba Bai

思路

分情况讨论:要做到不重不漏

A&&B一共会出现四种情况

A:T B:T

A:T B:F

A:F B:T

A:F B:F

使用两个数组分别去存储数字的汉字和单位

为了保证按照格式输出首先输出最高位,然后再空格输出下一位

输出接下来的数字时,当数字不为零时,输出它的数字和单位

当数字为零时:数字所在单位代表的进制:如果数字所在单位的所有位不全为 零,输出进制

零的输出:只要零后面还有零就需要输出零,连续的零只需要输出一个零

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
using namespace std;

/*
    分情况讨论:要做到不重不漏
    A&&B一共会出现四种情况
    A:T  B:T
    A:T  B:F
    A:F  B:T
    A:F  B:F
    使用两个数组分别去存储数字的汉字和单位
    为了保证按照格式输出首先输出最高位,然后再空格输出下一位
    输出接下来的数字时,当数字不为零时,输出它的数字和单位
    当数字为零时:数字所在单位代表的进制:如果数字所在单位的所有位不全为零,输出进制
    零的输出:只要零后面还有零就需要输出零,连续的零只需要输出一个零*/

int main()
{
    int n;
    string arr1[10] = {
        "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    string arr2[9] = {"", "Shi", "Bai", "Qian", "Wan", "Shi", "Bai", "Qian", "Yi"};
    while (scanf("%d", &n) != EOF)
    {
        int flag = 0;
        if (n < 0)
        {
            n = -n;
            flag = 1;
        }
        int num[20], index = 0;
        do
        {
            num[index++] = n % 10;
            n = n / 10;
        } while (n != 0);
        if (flag)
            printf("Fu ");
        printf("%s", arr1[num[index - 1]].c_str());
        if (index != 1)  printf(" %s", arr2[index - 1].c_str());
        int flag1 = 0, count = 0;
        for (int i = index - 2; i >= 0; i--)
        {
            if (num[i] == 0)
            {
                flag1 = 1;
                count++;
                //万进制的输出,描述不太准确:只要万进制的位不全为零,就要输出万
                if (i == 4)  printf(" %s", arr2[i].c_str());
                continue;
            }
            if (flag1)
            {
                printf(" ling");
                flag1 = 0;
                count = 0;
            }
            printf(" %s", arr1[num[i]].c_str());
            if (i != 0)  printf(" %s", arr2[i].c_str());
        }
    }
    return 0;
}

1048 数字加密

1048 数字加密

本题要求实现一种数字加密方法。首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 10、Q 代表 11、K 代表 12;对偶数位,用 B 的数字减去 A 的数字,若结果为负数,则再加 10。这里令个位为第 1 位。

输入格式:

输入在一行中依次给出 A 和 B,均为不超过 100 位的正整数,其间以空格分隔。

输出格式:

在一行中输出加密后的结果。

输入样例:

1
1234567 368782971

输出样例:

1
3695Q8118

思路

将A、B进行reverse,然后再进行加密

首先取A、B里面的长度较小值,然后进行对应位加密

最后倒序输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <algorithm>
using namespace std;

/*
    将A、B进行reverse,然后再进行加密
    首先取A、B里面的长度较小值,然后进行对应位加密
    最后倒序输出 */

int main()
{
    string a, b;
    char arr[13] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K'};
    while (cin >> a >> b)
    {
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        int len = min(a.size(), b.size());
        int num[1005];
        for (int i = 0; i < len; i++)
        {
            if ((i + 1) % 2 != 0)
            {
                num[i] = ((b[i] - '0') + (a[i] - '0')) % 13;
            }
            else
            {
                num[i] = (b[i] - '0') - (a[i] - '0');
                if (num[i] < 0)
                    num[i] += 10;
            }
        }
        int l = max(a.size(), b.size());
        if (a.size() > b.size())
        {
            for (int j = len; j < l; j++)
            {
                if ((j + 1) % 2 != 0)
                {
                    num[j] = (a[j] - '0') % 13;
                }
                else
                {
                    num[j] = 0 - (a[j] - '0');
                    if (num[j] < 0)
                        num[j] += 10;
                }
            }
        }
        else
        {
            for (int j = len; j < l; j++)
            {
                if ((j + 1) % 2 != 0)
                {
                    num[j] = (b[j] - '0') % 13;
                }
                else
                {
                    num[j] = b[j] - '0';
                }
            }
        }

        for (int i = l - 1; i >= 0; i--)
        {
            printf("%c", arr[num[i]]);
        }
    }
    return 0;
}

1077 Kuchiguse

The Japanese language is notorious for its sentence ending particles. Personal preference of such particles can be considered as a reflection of the speaker’s personality. Such a preference is called “Kuchiguse” and is often exaggerated artistically in Anime and Manga. For example, the artificial sentence ending particle “nyan~” is often used as a stereotype for characters with a cat-like personality:

  • Itai nyan~ (It hurts, nyan~)
  • Ninjin wa iyada nyan~ (I hate carrots, nyan~)

Now given a few lines spoken by the same character, can you find her Kuchiguse?

Input Specification:

Each input file contains one test case. For each case, the first line is an integer N (2≤N≤100). Following are N file lines of 0~256 (inclusive) characters in length, each representing a character’s spoken line. The spoken lines are case sensitive.

Output Specification:

For each test case, print in one line the kuchiguse of the character, i.e., the longest common suffix of all N lines. If there is no such suffix, write nai.

Sample Input 1:

1
2
3
4
3
Itai nyan~
Ninjin wa iyadanyan~
uhhh nyan~

Sample Output 1:

1
nyan~

Sample Input 2:

1
2
3
4
3
Itai!
Ninjinnwaiyada T_T
T_T

Sample Output 2:

1
nai

思路

使用字符串进行输入的时候空格会结束输入

寻找最长后缀匹配不太方便,我们可以对它进行变换

转变为寻找最长前缀匹配

首先,对所有的字符串进行reverse

然后再将第一个字符串的每个单词和其他所有的字符串进行比较,

发现出现不一样的单词就停止进行比对

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <algorithm>
using namespace std;

/*
    使用字符串进行输入的时候空格会结束输入
    寻找最长后缀匹配不太方便,我们可以对它进行变换
    转变为寻找最长前缀匹配
    首先,对所有的字符串进行reverse
    然后再将第一个字符串的每个单词和其他所有的字符串进行比较,
    发现出现不一样的单词就停止进行比对
     */

int main()
{
    int n;
    string sen[1005];
    while (scanf("%d", &n) != EOF)
    {
        getchar();
        for (int i = 0; i < n; i++)
        {
            getline(cin, sen[i]);
            reverse(sen[i].begin(), sen[i].end());
        }
        int len = sen[0].size(), flag = 0, index = 0;
        for (int i = 0; i < len; i++)
        {
            char c = sen[0][i];
            for (int j = 1; j < n; j++)
            {
                if (sen[j][i] != c)
                {
                    flag = 1;
                    break;
                }
            }
            if (flag)
            {
                index = i - 1;
                break;
            }
        }
        if (index < 0)
        {
            printf("nai");
        }
        else
        {
            for (int i = index; i >= 0; i--)
            {
                printf("%c", sen[0][i]);
            }
        }

        printf("\n");
    }
    return 0;
}

1009 说反话

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子。

输入样例:

1
Hello World Here I Come

输出样例:

1
Come I Here World Hello

思路

首先使用一个字符串来接受每个单词,然后再使用一个数组来接受所有的单词,随后把句子倒序输出。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

/* 
    用一个字符串接受输入的每个单词
    然后使用一个字符串数组接受输入的每个单词 */

int main()
{
    string s, arr[10005];
    int num;
    while (cin >> s)  arr[num++] = s;
    cout << arr[num - 1];
    for (int i = num - 2; i >= 0; i--)
    {
        cout << " " << arr[i];
    }
    return 0;
}