[HW] OJ记录20题之一

注意

int main()
{
    int n;
    cin>>n;
    while (n--)
    {
        char ch[100];
        cin>>ch; 
        //此处用gets(ch)或者cin.getline(ch,100)出现问题
        //原因在于输入n后残留了一个回车键,可用getchar()获取。
        cout<<fun(ch)<<endl;
    }
    return 0;
}

1 删除字符串中出现次数最少的字符

特殊案例(输入:aaa,输出:NULL)

#include <iostream>
#include <cstring>
using namespace std;

void fun(const char *src, char *dest);
int main()
{
    char ch[21];
    while (cin>>ch)
    {
        char dest[21] = {0};
        fun(ch, dest);
        cout<<dest<<endl;
    }

    return 0;
}

void fun(const char *src, char *dest)
{
    int c[26] = {0};
    int least = 20;
    for (int i = 0; i < strlen(src); i++)
    {
        c[src[i]-'a']++;
    }

    for (int i = 0; i < 26; i++)
    {
        if (c[i] != 0)
        {
            least = min(least, c[i]);
        }
    }

    while ('\0' != *src)
    {
        if (c[*src-'a'] != least)
        {
            *dest++ = *src;
        }
        src++;
    }
    *dest = '\0';
}

2 输入n个整数,输出其中最小的k个

#include <iostream>
#include <cstring>
using namespace std;

bool GetMinK(unsigned int uiInputNum, int * pInputArray, unsigned int uiK, int * pOutputArray);
int main()
{
    int uiInputNum, uiK;
    while (cin>>uiInputNum>>uiK)
    {
        int *pInputArray = new int[uiInputNum];
        for (int i = 0; i < uiInputNum; i++)
        {
            cin>>pInputArray[i];
        }

        int *pOutputArray = new int[uiK];
        GetMinK(uiInputNum, pInputArray, uiK, pOutputArray);

        for (int i = 0; i < uiK; i++)
        {
            if (i != uiK - 1)
            {
                cout<<pOutputArray[i]<<" ";
            }
            else
            {
                cout<<pOutputArray[i];
            }
        }
        cout<<endl;

        delete [] pInputArray;
        delete [] pOutputArray;
    }

    return 0;
}

bool GetMinK(unsigned int uiInputNum, int * pInputArray, unsigned int uiK, int * pOutputArray)
{
    for (int i = 0; i < uiK; i++)
    {
        int k = i;
        for (int j = i + 1; j < uiInputNum; j++)
        {
            if (pInputArray[j] < pInputArray[k])
            {
                k = j;
            }
        }

        if (k != i)
        {
            int temp = pInputArray[k];
            pInputArray[k] = pInputArray[i];
            pInputArray[i] = temp;
        }
    }

    for (int i = 0; i < uiK; i++)
    {
        pOutputArray[i] = pInputArray[i];
    }

    return true;
}

3 合法IP

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

bool fun(char *str);

int main()
{
    char str[16];
    while (cin.getline(str, 16) && strlen(str) != 0)
    {
        if (fun(str))
        {
            cout<<"YES"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
        }
    }

    return 0;
}

bool fun(char *str)
{
    int b[3] = {-1};
    int n = 0;
    int bi = 0;
    for (int i = 0; i < strlen(str); i++)
    {
        if (str[i] == '.')
        {
            b[bi++] = i;
            if (n < 0 || n > 255)
            {
                return false;
            }

            n = 0;
        }
        else
        {
            n = n * 10 + str[i] - '0';
        }
    }

    if (b[0] == 0 || b[2] == strlen(str) - 1 || b[0] == -1 || b[1] == -1 || b[2] == -1
        || b[0] == b[1] || b[1] == b[2] || b[2] == b[3])
    {
        return false;
    }

    return true;
}

4 句子逆序

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

void reverse(char *str, int begin, int end);

int main()
{
    char ch[100];
    while (cin.getline(ch, 100) && strlen(ch) != 0)
    {
        reverse(ch, 0, strlen(ch) - 1);
        int begin = 0, end = 0;
        for (int i = 0; i < strlen(ch); i++)
        {
            if (ch[i] != ' ')
            {
                end = i;
            }
            else
            {
                reverse(ch, begin, end);
                begin = i + 1;
                end = i + 1;
            }
        }
        reverse(ch, begin, end);
        cout<<ch<<endl;
    }
    return 0;
}

void reverse(char *str, int begin, int end)
{
    char *left = str + begin;
    char *right = str + end;
    while (left < right)
    {
        char ch = *left;
        *left++ = *right;
        *right-- = ch;
    }
}

5 白钱买白鸡问题

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin>>n;
    for (int i = 0; i <= 100 / 5; i++)
    {
        for (int j = 0; j <= 100 / 3; j++)
        {
            int k = 100 - i - j;
            if (5 * i + 3 * j + k / 3.0 == 100)
            {
                cout<<i<<" "<<j<<" "<<k<<endl;
            }
        }
    }
    return 0;
}

6 名字的漂亮度

每个字符都有一个漂亮度,求名字的最大漂亮度。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int fun(char *str);

int main()
{
    int n;
    cin>>n;
    while (n--)
    {
        char ch[100];
        cin>>ch; //此处用gets(ch)或者cin.getline(ch,100)出现问题
        cout<<fun(ch)<<endl;
    }
    return 0;
}

int fun(char *str)
{
    int c[26] = {0};
    for (int i = 0; i < strlen(str); i++)
    {
        if (str[i] >= 'a' && str[i] <= 'z')
        {
            c[str[i]-'a']++;
        }
        else if (str[i] >= 'A' && str[i] <= 'Z')
        {
            c[str[i]-'A']++;
        }
    }

    //sort the count of characters
    for (int i = 0; i < 26 - 1; i++)
    {
        int k = i;
        for (int j = i + 1; j < 26; j++)
        {
            if (c[j] < c[k])
            {
                k = j;
            }
        }

        if (k != i)
        {
            char temp = c[k];
            c[k] = c[i];
            c[i] = temp;
        }
    }

    int sum = 0;
    int n = 1;
    for (int i = 0; i < 26; i++)
    {
        sum += c[i] * n++;
    }

    return sum;
}

7 字符串分割

输入:
2
abc
123456789
输出:
abc00000
12345678
90000000
(注意:空字符串不处理)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

void fun(char *str);

int main()
{
    int n;
    cin>>n;
    while (n--)
    {
        char ch[101];
        cin>>ch;
        fun(ch);
    }

    return 0;
}

void fun(char *str)
{
    if (strlen(str) == 0)
    {
        return;
    }
    int len = strlen(str);
    while (len % 8 != 0)
    {
        len++;
    }

    char word[9] = {0};
    int index = 0;
    int i = 0;
    while ('\0' != *str)
    {
        while ('\0' != *str && i < 8)
        {
            word[i++] = *str++;
            index++;
        }
        if (i == 8)
        {
            word[i] = '\0';
            cout<<word<<endl;
            i = 0;
        }
    }

    if (index < len)
    {
        while (index < len)
        {
            word[i++] = '0';
            index++;
        }
        word[i++] = '\0';
        cout<<word<<endl;
    }
}

8 查找输入二进制整数中1的个数(不使用位运算)

#include <iostream>
using namespace std;

int fun(int n);
int fun2(int n);

int main()
{
    int n;
    while (cin>>n)
    {
        cout<<fun(n)<<endl;
        cout<<fun2(n)<<endl;
    }

    return 0;
}

int fun(int n)
{
    int count = 0;
    while (n)
    {
        n &= n - 1;
        count++;
    }

    return count;
}

int fun2(int n)
{
    if (n >= 0)
    {
        int count = 0;
        while (n)
        {
            count += n % 2;
            n /= 2;
        }
        return count;
    }
    else
    {
        return 32 - fun2(-n - 1);
    }
}

9 等差数列求和

2 5 8 11 ……
输入:2
输出:7

(用公式求和)

#include <iostream>
using namespace std;

int main()
{
    int n;
    while (cin>>n)
    {
        cout<<1.5 * n * n + 0.5 * n<<endl;
    }

    return 0;
}

10 字符串匹配

判断是否一个字符串中所有的字符都在第二个字符串中出现
输入:
ab
abc
输出:
true

#include <iostream>
#include <cstdio>
using namespace std;

bool IsAllCharExist(char* pShortString,char* pLongString);

int main()
{
    char pShort[100];
    char pLong[100];
    while (gets(pShort) && gets(pLong))
    {
        if (IsAllCharExist(pShort, pLong))
        {
            cout<<"true"<<endl;
        }
        else
        {
            cout<<"false"<<endl;
        }
    }

    return 0;
}

bool IsAllCharExist(char* pShortString,char* pLongString)
{
    bool s[256] = {false};
    while ('\0' != *pShortString)
    {
        s[*pShortString++] = true;
    }

    while ('\0' != *pLongString)
    {
        s[*pLongString++] = false;
    }

    for (int i = 0; i < 256; i++)
    {
        if (s[i])
        {
            return false;
        }
    }

    return true;
}

11 字符统计

统计其中的大小写字母,空格和数字,按个数从多到少输出,若个数一样则先输出SCII码比较小的。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

void fun(char *src, char *dest);

int main()
{
    char src[100];
    while (gets(src))
    {
        char dest[100];
        fun(src, dest);
        cout<<dest<<endl;
    }

    return 0;
}

void fun(char *src, char *dest)
{
    int c[123] = {0};
    for (int i = 0; i < strlen(src); i++)
    {
        if (src[i] < 123)
        c[src[i]]++;
    }

    int index = 0;
    for (int j = 1; j < 53; j++) //53是所有要统计字符的个数
    {
        int max = c[32];
        int curIndex = 32;
        for (int i = 48; i < 123; i++)
        {
            if ((i >= 58 && i <= 64) || (i >= 91 && i <= 96))
            {
                continue;
            }
            else
            {
                if (c[i] > max)
                {
                    max = c[i];
                    curIndex = i;
                }
            }
        }

        if (max == 0) //统计已经完成
        {
            break;
        }
        dest[index++] = curIndex;
        c[curIndex] = 0;
    }
    dest[index++] = '\0';
}

12 进制转化

输入:0xA
输出:10

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

void HEX2DEC(char *src, char *dest);
int fun(char c);
void itoa(int n, char *str);
void reverse(char *str);

int main()
{
    char src[10];
    while (gets(src))
    {
        char dest[11];
        HEX2DEC(src, dest);
        cout<<dest<<endl;
    }

    return 0;
}

void HEX2DEC(char *src, char *dest)
{
    int sum = 0;
    for (int i = 2; i < strlen(src); i++)
    {
        sum = sum * 16 + fun(src[i]);
    }

    itoa(sum, dest);
}

int fun(char c)
{
    if (c >= '0' && c <= '9')
    {
        return c - '0';
    }
    else if (c >= 'A' && c <= 'F')
    {
        return c - 'A' + 10;
    }
}

void itoa(int n, char *str)
{
    int i = 0;
    while (n)
    {
        str[i++] = n % 10 + '0';
        n /= 10;
    }
    str[i++] = '\0';
    reverse(str);
}

void reverse(char *str)
{
    char *left = str;
    char *right = str + strlen(str) - 1;
    while (left < right)
    {
        char c = *left;
        *left++ = *right;
        *right-- = c;
    }
}

#include <cstdio>
int main()
{
    int n;
    scanf("%x", &n);
    printf("%d", n);

    return 0;
}

13 提取不重复整数

从右边开始往左边读,如果以0开头,则去掉0。
输入:
0000
123355660
输出:
0
65321

#include <iostream>
#include <cstring>
using namespace std;

void fun(char *src, char *dest);

int main()
{
    char src[11];
    while (cin>>src)
    {
        char dest[11];
        fun(src, dest);
        if (dest[0] == '0' && strlen(dest) != 1)
        {
            cout<<dest+1<<endl;
        }
        else
        {
            cout<<dest<<endl;
        }
    }
}

void fun(char *src, char *dest)
{
    int j = 0;
    bool hash[10] = {false};
    for (int i = strlen(src) - 1; i >= 0; i--)
    {
        if (!hash[src[i]-'0'])
        {
            hash[src[i]-'0'] = true;
            dest[j++] = src[i];
        }
    }
    dest[j++] = '\0';
}

14 超长正整数相加

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

string fun(string n1, string n2);

int main()
{
    string n1, n2;
    while (cin>>n1 && cin>>n2)
    {
        cout<<fun(n1, n2).c_str()<<endl;
    }
}

string fun(string n1, string n2)
{
    string n = "";
    int num = 0;
    int i = n1.size() - 1;
    int j = n2.size() - 1;
    for (; i >= 0 && j >= 0; i--, j--)
    {
        num += n1[i] - '0' + n2[j] - '0';
        n += num % 10 + '0';
        num /= 10;
    }

    while (i >= 0)
    {
        num += n1[i--] - '0';
        n += num % 10 + '0';
        num /= 10;
    }

    while (j >= 0)
    {
        num += n2[j--] - '0';
        n += num % 10 + '0';
        num /= 10;
    }

    if (num != 0)
    {
        n += num + '0';
    }

    reverse(n.begin(), n.end());
    return n;
}

三个循环可以合为一个。

15 图片整理

实际为字符排序。
如果用string str,直接sort(str.begin(), str.end()),需要包含<algorithm>;

#include <iostream>
#include <cstring>
using namespace std;

void sort(char *str);

int main()
{
    char ch[1025];
    while (cin>>ch)
    {
        sort(ch);
        cout<<ch<<endl;
    }
}

void sort(char *str)
{
    int len = strlen(str);
    for (int i = 0; i < len - 1; i++)
    {
        int j = i;
        for (int k = i + 1; k < len; k++)
        {
            if (str[k] < str[j])
            {
                j = k;
            }
        }

        if (j != i)
        {
            char c = str[j];
            str[j] = str[i];
            str[i] = c;
        }
    }
}

16 在字符串中找出连续最长的数字串

输出最长的数字串及其个数
输入:
abcd123afd1234daf
ab
输出:
1234,4
0

#include <iostream>
#include <cstring>
using namespace std;

unsigned int Continumax(char* pOutputstr,  char* pIntputstr);

int main()
{
    char ch[100];
    while (cin.getline(ch, 100))
    {
        char output[100] = {0};
        int n = Continumax(output, ch);
        if (strlen(output) == 0)
        {
            cout<<n<<endl;
        }
        else
        {
            cout<<output<<","<<n<<endl;
        }
    }

    return 0;
}

unsigned int Continumax(char* pOutputstr,  char* pInputstr)
{
    int len = strlen(pInputstr);
    int max = 0;
    int max_left = 0;
    int max_right = 0;
    int left = 0;
    int right = 0;
    for (int i = 0; i < len; i++)
    {
        if (pInputstr[i] >= '0' && pInputstr[i] <= '9')
        {
            right = i;
            if (right - left + 1 > max)
            {
                max = right - left + 1;
                max_left = left;
                max_right = right;
            }
        }
        else
        {
            left = i + 1;
            right = i + 1;
        }
    }

    if (max == 0)
    {
        return 0;
    }

    for (int i = max_left; i <= max_right; i++)
    {
        *pOutputstr++ = pInputstr[i];
    }
    *pOutputstr = '\0';

    return max;
}

17 简单密码破解

小写字母对应为手机键盘对应的数字。明码中的大写字母转成原来的小写字母是通过,先变成小写,然后ASCII码再加1。输入为明码,输出为密码。

#include <iostream>
#include <cstring>
using namespace std;

void fun(char *str);

int main()
{
    char ch[100];
    while (cin.getline(ch, 100))
    {
        fun(ch);
        cout<<ch<<endl;
    }

    return 0;
}

void fun(char *str)
{
    int n[26] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
    for (int i = 0; i < strlen(str); i++)
    {
        if (str[i] >= 'A' && str[i] <= 'Z')
        {
            str[i] = str[i] + 32  + 1;
            if (str[i] > 'z')
            {
                str[i] = 'a';
            }
        }
        else if (str[i] >= 'a' && str[i] <= 'z')
        {
            str[i] = n[str[i] - 'a'] + '0';
        }
    }
}

18 [中级]单词倒排

将单词倒序排列,中间的空格或其他字符都作为分隔符,输出中的分隔符只能有一个空格,不能有其他符号。
输入:
I am a boy
I 4324 /*- - - /-// fdsf
输出:
boy a am I
fdsf I

#include <iostream>
#include <cstring>
using namespace std;

void fun(char *dest, const char *src);

int main()
{
    char ch[100];
    while (cin.getline(ch, 100))
    {
        char dest[100];
        fun(dest, ch);
        cout<<dest<<endl;
    }

    return 0;
}

void fun(char *dest, const char *src)
{
    int len = strlen(src);
    int i = len - 1;
    int right = i;
    int left = i;
    int count = 0;
    while (i >= 0)
    {
        if ((src[i] >= 'A' && src[i] <= 'Z') || (src[i] >= 'a' && src[i] <= 'z'))
        {
            left = i;
            count++;
        }
        else
        {
            if (count != 0)
            {
                while (left <= right)
                {
                    *dest++ = src[left++];
                }
                *dest++ = ' ';
            }
            left = i - 1;
            right = i - 1;
            count = 0;
        }
        i--;
    }

    //最后的这一个单词最容易忘记
    if (count != 0)
    {
        while (left <= right)
        {
            *dest++ = src[left++];
        }
    }
    *dest = '\0';
}

19 输出单向链表中倒数第k个结点

尾结点为倒数第0个。

#include <iostream>
using namespace std;

struct ListNode
{
    int m_nKey;
    ListNode *m_pNext;
    ListNode(int x) : m_nKey(x), m_pNext(NULL) {}
};
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k);
void print(ListNode *head);

int main()
{
    int n;
    while (cin>>n)
    {
        ListNode *head = new ListNode(-1);
        ListNode *pre = head;
        while (n--)
        {
            int val;
            cin>>val;
            ListNode *cur = new ListNode(val);
            pre->m_pNext = cur;
            pre = cur;
        }
        int k;
        cin>>k;

        ListNode *p = FindKthToTail(head->m_pNext, k);
        cout<<p->m_nKey<<endl;
    }

    return 0;
}

ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
    ListNode *p1 = pListHead;
    ListNode *p2 = pListHead;
    while (k--)
    {
        p1 = p1->m_pNext;
    }

    while (p1->m_pNext != NULL)
    {
        p1 = p1->m_pNext;
        p2 = p2->m_pNext;
    }

    return p2;
}

20 取近似值

差不多就是四舍五入吧

#include <iostream>
using namespace std;

int main()
{
    float n;
    while (cin>>n)
    {
        n >= 0 ? cout<<(int)(n + 0.5)<<endl : cout<<(int)(n - 0.5)<<endl;
    }
    return 0;
}

你可能感兴趣的:([HW] OJ记录20题之一)