天方夜谭之——c算法题库1

"天方夜谭之——c算法题库1"

引言

在本文列举了常用 c算法,程包括程序设计思想、代码。

01 字符串最后一个单词的长度

描述
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。
(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。

输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。

示例1
输入:
hello nowcoder

输出:
8

说明:
最后一个单词为nowcoder,长度为8
思想:
字符串fgets(s,5000,stdin);
循环 由后向前判断,并计数,如果if(s[le-i]==’ ')条件满足,则退出循环,输出计数值num.
代码

#include<stdio.h>
#include<string.h>

int main()
{
    char s[5000];
    int num = 0;
    fgets(s,5000,stdin);
    
    int le = strlen(s) - 1;
    //printf("%d\n",strlen(s));
    for(int i=1;i<=le;i++)
    {
        if(s[le-i]==' ')
        {
            //printf("%d\n",num);
            break;
        }
        else
        {
            num++;
        }
    }
    printf("%d\n", num);
   return 0; 
}

02 计算某字符出现次数

描述
写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)

数据范围:
输入描述:
第一行输入一个由字母和数字以及空格组成的字符串,第二行输入一个字符。

输出描述:
输出输入字符串中含有该字符的个数。(不区分大小写字母)

示例1
输入:
ABCabc
A
输出:
2
思想
获取字符串fgets(str, sizeof(str), stdin);
判断输入的是大写字母或者小写字母
判断被比较的字符串中是大写或是小写: if (str[i] == ch || str[i] == ch+32)
if (str[i] == ch || str[i] == ch-32)
代码

#include <stdio.h>

int main(void)
{
    char str[1000] = {0}, ch = 0;
    fgets(str, sizeof(str), stdin);
    ch = getchar();//fgetc(stdin);

    int str_len = strlen(str) - 1;
    if (str_len == 0) {
        printf("0\n");
        return 0;
    }

    int count = 0, i = 0;
    if (ch >= 'A' && ch <= 'Z') {
        for (i = 0; i < str_len; i++) {
            if (str[i] == ch || str[i] == ch+32)
                count++;
        }
    } else if (ch >= 'a' && ch <= 'z') {
        for (i = 0; i < str_len; i++) {
            if (str[i] == ch || str[i] == ch-32)
                count++;
        }
    } else {
        for (i = 0; i < str_len; i++) {
            if (str[i] == ch)
                count++;
        }
    }

    printf("%d\n", count);
    return 0;
}

03 明明的随机数

描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数( N≤1000 ),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作(同一个测试用例里可能会有多组数据(用于不同的调查),希望大家能正确处理)。

注:测试用例保证输入参数的正确性,答题者无需验证。测试用例不止一组。

当没有新的输入时,说明输入结束。

数据范围: ,输入的数字大小满足
输入描述:
注意:输入可能有多组数据(用于不同的调查)。每组数据都包括多行,第一行先输入随机整数的个数 N ,接下来的 N 行再输入相应个数的整数。具体格式请看下面的"示例"。

输出描述:
返回多行,处理后的结果
示例1
输入:
3
2
2
1
11
10
20
40
32
67
40
20
89
300
400

输出:
1
2
10
15
20
32
40
67
89
300
400

说明:
示例1包含了两个小样例!!
输入解释:
第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到1000之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以第一个小样例的输出为:
1
2
第二个小样例的第一个数字为11,也即…(类似上面的解释)…
所以第二个小样例的输出为:
10
15
20
32
40
67
89
300
400
代码

#include <stdio.h>
#include <string.h>

int cnt[1001];

int main()
{
    int n, x;

    while (scanf("%d", &n) != EOF) {
        memset(cnt, 0, sizeof(cnt));

        for (int i = 0; i < n; ++i) {
            scanf("%d", &x);
            cnt[x] = 1;
        }

        for (int i = 1; i <= 1000; ++i)
            if (cnt[i]) printf("%d\n", i);
    }

    return 0;
}

04 字符串分隔

描述
•连续输入字符串,请按长度为8拆分每个输入字符串并进行输出;
•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
(注:本题有多组输入)
输入描述:
连续输入字符串(输入多次,每个字符串长度小于等于100)

输出描述:
依次输出所有分割后的长度为8的新字符串

示例1
输入:
abc
123456789

输出:
abc00000
12345678
90000000
代码

#include <stdio.h>

int main()
{
    char s[100];

    while (scanf("%s", s) != EOF) {
        char* ps = s, cnt = 0;

        while (*ps != '\0') {
            putchar(*ps++);

            if (++cnt == 8) {
                putchar('\n');
                cnt = 0;
            }
        }

        if (*ps == '\0' && cnt != 0) {
            while (cnt++ != 8) putchar('0');
            putchar('\n');
        }
    }

    return 0;
}

05 进制转换

描述
写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。

数据范围:保证结果在

注意本题有多组输入
输入描述:
输入一个十六进制的数值字符串。注意:一个用例会同时有多组输入数据,请参考帖子https://www.nowcoder.com/discuss/276处理多组输入的问题。

输出描述:
输出该数值的十进制字符串。不同组的测试用例用\n隔开。

示例1
输入:
0xA
0xAA

输出:
10
170
代码

#include "string.h"
#include "stdio.h"

int main(void)
{
    int num=0;
    while(scanf("%i\n",&num)!=-1)
    {
        printf("%d\n",num);
    }
    return 0;
}

06 质数因子

描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )

数据范围:
输入描述:
输入一个整数

输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。

示例1
输入:
180

输出:
2 2 3 3 5
思想:
输入的数据num可以除以整除2或者3以及3+2*n的小于num的数,将可以整除的数据存储质数因子int数组.
if((num%data)0)
{
num/=data;
buf[count++]=data;
data=2;
}
else{
if(data
2)
data++;
else
data+=2;
}

代码:

#include "stdio.h"
#include "string.h"

int main(void)
{
    int num=0;
    scanf("%ld",&num);
    int buf[100]={0};
    int count=0;
    int data=2;
    while(num!=1)
    {
        if((num%data)==0)
        {
            num/=data;
            buf[count++]=data;
            data=2;
        }
        else{
            if(data==2)
                data++;
            else
                data+=2;
        }
    }
    for(int i=0;i<count;i++)
    {
        printf("%d ",buf[i]);
    }
    return 0;
}

07 求近似值

描述
描述
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。

数据范围:保证输入的数字在 32 位浮点数范围内
输入描述:
输入一个正浮点数值
输出描述:
输出该数值的近似整数值
示例1
输入:
5.5

输出:
6

说明:
0.5>=0.5,所以5.5需要向上取整为6
示例2
输入:
2.499
输出:
2
说明:
0.499<0.5,2.499向下取整为2

思想:
先乘以10倍,k=n*10;
判断十分位是否大于5, if((k%10)>=5)
代码

#include <stdio.h>

int main()
{    
    float n;
    int m,k;
    scanf("%f",&n);
    k=n*10;
    if((k%10)>=5)
    {
        m=((int)n)+1;
    }
    else
    {
        m=(int)n;
    }
    printf("%d",m);
}

08 合并记录表

描述
数据表记录包含表索引和数值(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

提示:
0 <= index <= 11111111
1 <= value <= 100000

输入描述:
先输入键值对的个数n(1 <= n <= 500)
然后输入成对的index和value值,以空格隔开

输出描述:
输出合并后的键值对(多行)

示例1
输入:
4
0 1
0 2
1 2
3 4

输出:
0 3
1 2
3 4

示例2
输入:
3
0 1
0 2
8 9

输出:
0 3
8 9

思想
int f[n][2];
代码

#include "stdio.h"

int main(){
    int n;
    while(scanf("%d", &n) != EOF){    //输入键值对个数
        int f[n][2];
        //输入各键值对
        for(int i = 0; i < n; i++)
            scanf("%d %d", &f[i][0], &f[i][1]);
        //对键值对按从小到大排序
        for(int i = 1; i < n; i++){
            for(int j = 0; j < n-i; j++){
                if(f[j][0] > f[j+1][0]){
                    int t1 = f[j][0];
                    f[j][0] = f[j+1][0];
                    f[j+1][0] = t1;
                    int t2 = f[j][1];
                    f[j][1] = f[j+1][1];
                    f[j+1][1] = t2;
                }
            }
        }
        //统计“键”的个数
        int counts = 1, temp = f[0][0];
        for(int i = 0; i < n; i++){
            if(temp != f[i][0]){
                counts++;
                temp = f[i][0];
            }
        }
        //初始化合并后的键值对数组中的“值”
        int e[counts][2];
        for(int i = 0; i < counts; i++)
            e[i][1] = 0;
        //合并键值对
        temp = f[0][0];
        for(int i = 0, j = 0; i < n; i++){
            if(temp != f[i][0]){
                j++;
                temp = f[i][0];
            }
            e[j][0] = f[i][0];
            e[j][1] += f[i][1];
        }
        //输出合并后的键值对
        for(int i = 0; i < counts; i++)
            printf("%d %d\n", e[i][0], e[i][1]);
    }
    return 0;
}

09 提取不重复的整数

描述
输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。(删除重复数组)
保证输入的整数最后一位不是 0 。

数据范围:
输入描述:
输入一个int型整数

输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

示例1
输入:
9876673

输出:
37689

思想
字符窜转整形 num[i]=(int)(str[i]-48);
数组去重
if(num[j] == num[i])
{
for(k=j;k<len;k++)
{
num[k]=num[k+1];
}
len–;
j–;
代码

#include <stdio.h>
#include <string.h>

int num[1000],len,i,j,k;
char str[1000];

int main()
{    
        gets(str);
        len=strlen(str);
        //字符串转换成整型
        for(i=0;i<len;i++)
        {
            num[i]=(int)(str[i]-48);
        }
        //数组去重
        for(i=len-1;i>=0;i--)
        {
            for(j=i-1;j>=0;j--)
            {
                if(num[j] == num[i])
                {
                    for(k=j;k<len;k++)
                    {
                        num[k]=num[k+1];
                    }
                    len--;
                    j--;
                }
            }
        }
             //倒叙输出
             for(i=0;i<len;i++)
             {
                 printf("%d",num[len-i-1]);
             }

    return 0;
}

10 字符个数统计

描述
编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。

数据范围:
输入描述:
输入一行没有空格的字符串。

输出描述:
输出 输入字符串 中范围在(0~127,包括0和127)字符的种数。

示例1
输入:
abc

输出:
3

示例2
输入:
aaa

输出:
1
思想
定义一个int数组int tmp[128]={0};存放128个字符的存储个数,如果重复则不计入。
asc=(int)str[i];
if(tmp[asc]==0)
{
tmp[asc]=1;
num++;
}
代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int num=0,len,i,j,k,asc;
int tmp[128]={0};
char str[400];
int main()
{
    gets(str);
    len=strlen(str);
    for(i=0;i<len;i++)
    {
        asc=(int)str[i];
        if(tmp[asc]==0)
        {
            tmp[asc]=1;
            num++;
        }
    }
    printf("%d",num);
    return 0;
}

或者
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int num=0,len,i,j,k,asc;
int tmp[128]={0};
char str[400];
int main()
{
    //gets(str);
    fgets(str, sizeof(str),stdin);
    len=strlen(str)-1;
    for(i=0;i<len;i++)
    {
        asc=(int)str[i];
        if(tmp[asc]==0)
        {
            tmp[asc]=1;
            num++;
        }
    }
    printf("%d",num);
    return 0;
}

11 数字颠倒

描述
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001

数据范围:
输入描述:
输入一个int整数

输出描述:
将这个整数以字符串的形式逆序输出

示例1
输入:
1516000

输出:
0006151

示例2
输入:
0

输出:
0
思想
输入值采用字符串形式scanf(“%s”,str);
输出字符串逆序输出printf(“%c”,str[i])
代码

#include <stdio.h>
int main()
{
    char str[32] = {0};
    scanf("%s",str);
    //gets(str);
    for(int i=strlen(str)-1;i>=0;i--)
    {
        printf("%c",str[i]);
    }
    printf("\n");
}

12 字符串反转

描述
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)

输入描述:
输入一行,为一个只包含小写字母的字符串。

输出描述:
输出该字符串反转后的字符串。

示例1
输入:
abcd

输出:
dcba
代码

#include <stdio.h>
#include <string.h>
int main()
{
    char s[1000];
    int i,j,len;
    char temp;
    gets(s);
    len=strlen(s);
    for(i=0,j=len-1;i<=len/2-1;i++,j--)
    {
        temp=s[i];
        s[i]=s[j];
        s[j]=temp;
    }
    puts(s);
 } 

13 句子逆序

描述
将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符

数据范围:输入的字符串长度满足

注意本题有多组输入
输入描述:
输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。

输出描述:
得到逆序的句子

示例1
输入:
I am a boy

输出:
boy a am I

示例2
输入:
nowcoder

输出:
Nowcoder
思想
输入是一个一维字符串数组;
单词逆序通过定义二维字符串数组,将每个单词定义一行,如下:
if(str1[k] != ’ ')
{
temp[i][j] = str1[k];
j++;
}
else
{
i++;
j=0;
continue;
}
判断一个字符串数组结束标志if(str1[k] == “\0”),则退出。
输出判断字符是否‘\0’为条件,输出单个、单个字符。
代码

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[1000] = {};
    char temp[500][100] = {};
    //scanf("%[^\n]",str1);
    //scanf("%[^\n]",str1);
    gets(str1);
    
    int i=0,j=0;
    for(int k=0;k<1000;k++)
    {
        if(str1[k] != ' ')
        {
            temp[i][j] = str1[k];
            j++;
        }
        else
        {
            i++;
            j=0;
            continue;
        }
        if(str1[k] == "\0")
        {
            break;
        }
    }
    for(;i>=0;i--)
    {
        for(j=0;j<100;j++)
        {
            if(temp[i][j] == '\0')
            {
                break;
            }
            printf("%c",temp[i][j]);
        }
        printf(" ");
    }
}

14 字符串排序

描述
给定 n 个字符串,请对 n 个字符串按照字典序排列。
输入描述:
输入第一行为一个正整数n(1≤n≤1000),
下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。

示例1
输入:
9
cap
to
cat
card
two
too
up
boat
boot

输出:
boat
boot
cap
card
cat
to
too
two
up
代码

int compare(char *s1,char *s2)
{
    int len=strlen(s1)>strlen(s2)?strlen(s2):strlen(s1);
    for(int i=0;i<len;i++)
    {
        if(s1[i]>s2[i]) return 1;
        else if(s1[i]<s2[i]) return -1;
    }
    if(strlen(s1)==strlen(s2)) return 0;
    else if(strlen(s1)>strlen(s2)) return 1;
    return -1;
}
void var(char *s1,char *s2)
{
    char c;
    int len=strlen(s1)>strlen(s2)?strlen(s1):strlen(s2);
    for(int i=0;i<len;i++)
    {
        c=s1[i];
        s1[i]=s2[i];
        s2[i]=c;
    }
}
int main(){
    char a[1024][100];
    int n;
    scanf("%d\n",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%s",a[i]);
    }
    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            if(compare(a[i],a[j])>0)
            {
                var(a[i],a[j]);
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        printf("%s\n",a[i]);
    }
    return 0;
}

或者

#include <stdio.h>
//在这里进行变型,比较的数组是个指针数组,需要对指针指向的内容进行比较
int cmp(const char** a, const char** b){
    return strcmp((char *)*a, (char *)*b);
}
int main(){
    int num = 0;
    scanf("%d\n",&num);
    char** str = (char**)malloc(sizeof(char*) * (num));  //指向二维数组,一维数组指针的二级指针 
    char* p = (char*)malloc(sizeof(char) * (num) * 101);   //为二维数组的每个元素分配空间
    memset(p, sizeof(char) * (num) * 101, 0);
    for(int i=0; i<num; i++){
        scanf("%s\n",p+i*101);
        str[i] = p+i*101; //str[i] 是二维数组的一维数组指针  str[i]  = *(str + i)
    }
    //利用strcmp比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。
    //strcmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,
    //若差值不为0 则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和'b'(98)的差值(-33)。
    qsort(str, num, sizeof(char *), cmp);
    for(int j=0; j<num; j++){
        printf("%s\n",str[j]);
    }
}

15 求int型正整数在内存中存储时1的个数

描述
输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。

数据范围:保证在 32 位整型数字范围内
输入描述:
输入一个整数(int类型)

输出描述:
这个数转换成2进制后,输出1的个数

示例1
输入:
5

输出:
2

示例2
输入:
0

输出:
0
代码

//n&(n-1)的操作表示将n最右边的一个1变为0,重复操作既可计算总共1的个数。
#include <stdio.h>
int main(){
    int n;
    int k = 0;
    scanf("%d",&n);
while(n){
    n&=(n-1);
    k++;
}
    printf("%d",k);
    return 0;
}

16 购物单

描述
主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅 无

如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号)
请你帮助王强设计一个满足要求的购物单。
输入描述:
输入的第 1 行,为两个正整数,用一个空格隔开:N m
(其中 N ( <32000 )表示总钱数, m ( <60 )为希望购买物品的个数。)
从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q
(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 ~ 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)
输出描述:
输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值( <200000 )。
示例1
输入:
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0

输出:
2200

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

int main(void){
    int N,m; // N:钱,M总物品数
    scanf("%d %d",&N,&m);
    int x,y,z;
    int value[m][4];// 价钱与重要度乘积
    int cost[m][4];// 价钱,0:主;1、2:附
    memset(value, 0, m * 4 * sizeof(int));
    memset(cost, 0, m * 4 * sizeof(int));

    for(int i=0;i<m;i++){
        scanf("%d %d %d", &x, &y, &z);
        // 分主附件,转化01背包问题
        // 计算四种情况的value和cost
        if(z==0){
            value[i][0]=x*y;
            cost[i][0]=x;
        }
        else if(cost[z-1][1]==0){
            // 第z件为其主件,对应下标z-1
            cost[z-1][1]=x;
            value[z-1][1]+=x*y;
        }
        else{
            cost[z-1][2]=x;
            value[z-1][2]=x*y;
            cost[z-1][3] = cost[z-1][1]+cost[z-1][2];
            value[z-1][3] = value[z-1][1]+value[z-1][2];
        }
    }
    for(int i=0;i<m;i++){
        for(int k=1; k<4;k++){
            cost[i][k] += cost[i][0];
            value[i][k] += value[i][0];
        }
    }

//     for(int i=0; i<m; i++){
//         for(int k=0;k<4;k++)
//             printf("%d %d    ", cost[i][k], value[i][k]);
//         printf("\n");
//     }

    int dp[m+1][N+1];
    int max_v=0;
    memset(dp, 0, (m+1)*(N+1)*sizeof(int));
    // 可以考虑优化,0行略过
    for(int i=1; i<=m; i++){
        for(int j=10;j<=N;j+=10){
            max_v = dp[i-1][j];
            for(int k=0;k<4;k++){
                if(k>0 && cost[i-1][k]==cost[i-1][0])
                    break;
                if(j-cost[i-1][k]>=0)
                    max_v = max(max_v,dp[i-1][j-cost[i-1][k]]+value[i-1][k]);
            }
            dp[i][j] = max_v;
        }
    }
    printf("%d", dp[m][N]);
    return 0;
}

17 坐标移动

描述
开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A(或者D或者W或者S) + 数字(两位以内)
坐标之间以;分隔。
非法坐标点需要进行丢弃。如AA10; A1A; % ; YAD; 等。
下面是一个简单的例子 如:
A10;S20;W10;D30;X;A1A;B10A11;;A10;
处理过程:
起点(0,0)

  • A10 = (-10,0)
  • S20 = (-10,-20)
  • W10 = (-10,-10)
  • D30 = (20,-10)
  • x = 无效
  • A1A = 无效
  • B10A11 = 无效
  • 一个空 不影响
  • A10 = (10,-10)
    结果 (10, -10)
    数据范围:每组输入的字符串长度满足 ,坐标保证满足 ,且数字部分仅含正数
    注意请处理多组输入输出
    输入描述:
    一行字符串
    输出描述:
    最终坐标,以逗号分隔
    示例1
    输入:
    A10;S20;W10;D30;X;A1A;B10A11;;A10;

输出:
10,-10

示例2
输入:
ABC;AKL;DA1;

输出:
0,0
代码

#include "stdio.h"

int main(int argc, char *argv[])
{
    char str[10001] = {0};
    
    scanf("%s", str);
    
    char *p = str;
    int x = 0; // X坐标
    int y = 0; // Y坐标
    char d = 0x00; // 方向,0x00表示还没有匹配到方向
    int n = 0;//移动的步数
    
    while (*p != '\0') {
        //没有匹配到方向的时候去匹配方向
        if (!d) {
            if (*p == 'A' || *p == 'S' || *p == 'W' || *p == 'D') {
                //匹配到方向
                d = *p;
                p++;
                continue;
            } else {
                //匹配到非方向字符,跳过这些字符,直到匹配到下一个分号
                while( *p != '\0' && *p != ';') {
                    p++;
                }
            }
        }
        
        //已经匹配到方向
        if (d) {
            if (*p >= '0' && *p <= '9') {
                //计算移动的步数
                n *= 10;
                n += *p - '0';
            } else if (*p == ';'){
                //正确匹配结束,根据方向移动
                if (d == 'A') {
                    x -= n;
                } else if (d == 'D') {
                    x += n;
                } else if (d == 'S') {
                    y -= n;
                } else if (d = 'W') {
                    y += n;
                }
                //清空状态
                d = 0;
                n = 0;
            } else {
                //在匹配步数的过程中出现错误,则清空状态
                n = 0;
                d = 0;
            }
        }
        p++;
    }
    //输出
    printf("%d,%d", x, y);
}

18 识别有效的IP地址和掩码并进行分类统计

描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0-10.255.255.255
172.16.0.0-172.31.255.255
192.168.0.0-192.168.255.255

子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
(注意二进制下全是1或者全是0均为非法子网掩码)
注意:

  1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
  2. 私有IP地址和A,B,C,D,E类地址是不冲突的
    输入描述:
    多行字符串。每行一个IP地址和掩码,用~隔开。
    输出描述:
    统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
    示例1
    输入:
    10.70.44.68~255.254.255.0
    1.0.0.1~255.0.0.0
    192.168.0.2~255.255.255.0
    19…0.~255.255.255.0
    输出:
    1 0 1 0 0 2 1
    说明:
    10.70.44.68255.254.255.0的子网掩码非法,19…0.255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
    1.0.0.1~255.0.0.0是无误的A类地址;
    192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
    所以最终的结果为1 0 1 0 0 2 1
    示例2
    输入:
    0.201.56.50~255.255.111.255
    127.201.56.50~255.255.111.255

输出:
0 0 0 0 0 0 0

说明:
类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略

代码

 #include <stdio.h>
 #include <string.h>
#include <stdbool.h>
#define SIZE 32

// 判断掩码是否正确,正确为1,错误为0
int MaskJudgment(char* st, int len);
// 返回 0 错误,1 A, 2 B  3 C  4 D  5 E   6 无效  7 私有
int IpsJudgment(char *st, int len);
// 返回 0 错误,1 A, 2 B  3 C  4 D  5 E   6 无效  7 私有
int IpFrist(int hard, int scond);
int pows(int n, int k);
int main(void){
    int iptag[7] = {0}; // 0~4: A,B,C,D,E. 5:错误, 6,私有
    int temp;
    char str[SIZE], ips[SIZE], mask[SIZE];
    while(scanf("%s", str) != EOF){
        int i = 0;
        // 将str拆分为 ip 和 mask
        while(str[i] != '~'){
            ips[i] = str[i];
            i++;
        }
        ips[i] = '\0';
        temp = i + 1;
        i = 0;
        while(str[temp + i]){
            mask[i] = str[temp + i];
            i++;
        }
        mask[i] = '\0';
        // 判断
        int ip = IpsJudgment(ips, strlen(ips));
        int ms = MaskJudgment(mask, strlen(mask));
        if(ip == 6);// 无效ip 不做处理,
        else if(ip == 0) iptag[5]++; // IP输入错误
        else if(ip == 1)// A 类地址
            if(!ms) iptag[5]++;    // 掩码输入错误
            else iptag[0]++;
        else if(ip == 2)// B 类地址
            if(!ms) iptag[5]++;
            else iptag[1]++;
        else if(ip == 3)// C 类地址
            if(!ms) iptag[5]++;
            else iptag[2]++;
        else if(ip == 4)// D 类地址
            if(!ms) iptag[5]++;
            else iptag[3]++;
        else if(ip == 5) // E 类地址
            if(!ms) iptag[5]++;
            else iptag[4]++;
        else if(ip == 7) // 私有ip, 172无效地址中的私有地址
            if(!ms) iptag[5]++;
            else iptag[6]++;
        else if(ip == 17) // 10网段,A + 私
            if(!ms) iptag[5]++;
            else {
                iptag[0]++;
                iptag[6]++;
            }
        else if(ip == 37)// 192网段 C + 私
            if(!ms) iptag[5]++;
            else {
                iptag[2]++;
                iptag[6]++;
            }
    }
    // 输出
    for(int i = 0; i < 7; i++)
        printf("%d ",iptag[i]);
    return 0;
}

// 返回 0 错误,1 A, 2 B  3 C  4 D  5 E   6 无效  7 私有
int IpsJudgment(char* st, int len){
    int num, hard = -1, scond, mark = 0;
    for(int i = 0; i < len; i++){
        num = 0;
        int t = 0;
        while(*(st + i) != '.' && i != len){
            num = num * 10 + (*(st + i) - '0');
            i++;
            t = 1;// 用于判断输入是否为空
        }
        if(mark != -1) mark++;
        if(hard == -1) hard = num;
        if(mark == 2) scond = num;
        if(num > 255 || t == 0) mark = -1;
    }
    int s = IpFrist(hard, scond);
    if(s == 6) return 6;
    else if(mark == -1) return 0;
    else return s;
}
// 返回 0 错误,1 A, 2 B  3 C  4 D  5 E   6 无效  7 私有
int IpFrist(int hard, int scond){
    if(hard == 0) return 6;
    else if(hard >= 1 && hard < 127){
        if(hard == 10) return 17;
        else return 1;
    }
    else if(hard == 127){
        if(scond >= 16 && scond < 32) return 7;
        else return 6;
    }
    else if(hard >= 128 && hard < 192) return 2;
    else if(hard >= 192 && hard < 224) {
        if(hard == 192 && scond == 168) return 37;
        else return 3;
    }
    else if(hard >= 224 && hard < 240) return 4;
    else if(hard >= 240 && hard < 255) return 5;
    else return 0;
}

int MaskJudgment(char* st, int len){
    int mark = 0;
    int num;
    if(*st == 0) return 0;
    for(int i = len - 1; i >= 0; i--){
        num = 0;
        int tag = 0;
        while(*(st + i) != '.' && i >= 0){
            num += (*(st + i) - '0') * pows(10,tag);
            tag++;
            i--;
        }
        int size = 8;
        while(size--){
            if(!(num & 01) && mark != 0) return 0;
            if(num & 01 == 1) mark++;// 
            num >>= 1;
        }
    }
    if(mark == 32) return 0;// 255.255.255.255的情况
    else return 1;
}

int pows(int n, int k){
    int num = 1;
    for(int i = 0; i < k; i++) num *= n;
    return num;
}

19 简单错误记录

描述
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:

1、 记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是“相同”的错误记录。
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。也就是说,哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录
4、循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准

数据范围:错误记录数量满足,每条记录长度满足
输入描述:
每组只包含一个测试用例。一个测试用例包含一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:

示例1
输入:
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
E:\je\rzuwnjvnuz 633
C:\km\tgjwpb\gy\atl 637
F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
E:\ns\mfwj\wqkoki\eez 648
D:\cfmwafhhgeyawnool 649
E:\czt\opwip\osnll\c 637
G:\nt\f 633
F:\fop\ywzqaop 631
F:\yay\jc\ywzqaop 631
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645

输出:
rzuwnjvnuz 633 1
atl 637 1
rwyfvzsopsuiqjnr 647 1
eez 648 1
fmwafhhgeyawnool 649 1
c 637 1
f 633 1
ywzqaop 631 2

说明:
由于D:\cfmwafhhgeyawnool 649的文件名长度超过了16个字符,达到了17,所以第一个字符’c’应该被忽略。
记录F:\fop\ywzqaop 631和F:\yay\jc\ywzqaop 631由于文件名和行号相同,因此被视为同一个错误记录,哪怕它们的路径是不同的。
由于循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准,所以D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645不会被记录。
代码

#include<stdio.h>
#include<string.h>
typedef struct ErrRecord
{
    char name[20];
    int line;
    int count;
}ErrRecord;

int main()
{
    ErrRecord record[100];
    int rindex = -1;
    
    char str[100];
    int line;
    while(EOF != scanf("%s%d",str,&line))
    {
        int i,j;
        int len = strlen(str);
        char name[20];
        for(i=len-1;i>=0;i--)
        {
            if(str[i] == '\\')
               break;
        }
        //从i+1 下一位开始复制,还有考虑长度不能超过16
        if(i+1 < len -16)
        {
            strcpy(name, str+len-16);
        }else {
            strcpy(name, str+i+1);
        }
        int flag = 0;  //标志能否在前面发现相同的记录 1:发现,0:未发现。
        for(i=0;i<=rindex;i++)
        {
            if( (0 == strcmp(name, record[i].name)) && (line == record[i].line) )
            {
                record[i].count++;
                flag = 1;
                break;
            }
        }
        
        if(0 == flag)
        {
            ++rindex;
            strcpy(record[rindex].name, name);
            record[rindex].line = line;
            record[rindex].count = 1;
        }
        
    }
    if(rindex<8)
    {
        for(int i=0;i<=rindex;i++)
        {
            printf("%s %d %d \n",record[i].name,record[i].line,record[i].count);
        }
    }else {
        for(int i=rindex-7;i<=rindex;i++)
        {
            printf("%s %d %d \n",record[i].name,record[i].line,record[i].count);
        }
    }
    
    return 0;
}

20 密码验证合格程序

描述
密码要求:

1.长度超过8位

2.包括大小写字母.数字.其它符号,以上四种至少三种

3.不能有长度大于2的不含公共元素的子串重复 (注:其他符号不含空格或换行)

数据范围:输入的字符串长度满足

本题有多组输入
输入描述:
一组或多组字符串。每组占一行

输出描述:
如果符合要求输出:OK,否则输出NG

示例1
输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
输出:
OK
NG
NG
OK
代码

#include <stdio.h>

int main()
{
    char str[100]={'\0'};
    while(scanf("%s",&str)!=EOF)
    {

        int type[4]={0};//各种种类的密码是否出现过
        int dif=0;//记录密码中字符的种类
        int len=0;//密码串的长度
        char substr[3]={'\0'};//记录长度为3的子串
        int sub=0;//记录是否有长度超过2的重复子串
        int i,j,k=0;

        len=strlen(str);

        //含有的字符种类判断
        for(i=0;i<len;i++)
        {
            if(str[i]>='A'&&str[i]<='Z')
                type[0]=1;
            else if(str[i]>='a'&&str[i]<='z')
                   type[1]=1;
            else if(str[i]>='0'&&str[i]<='9')
                    type[2]=1;
            else
            type[3]=1;
        }
        dif=type[0]+type[1]+type[2]+type[3];

        //判断是否有重复的子串
        for(i=0;i<(len-3);i++)
        {
            substr[0]=str[i];
substr[1]=str[i+1];
substr[2]=str[i+2];

            for(j=i+3;j<(len-3);j++)
            {
                if(str[j]==substr[0])
                {
                    if(str[j+1]==substr[1])
                    {
                        if(str[j+2]==substr[2])
                        {
                            sub=1;
                        }
                    }
                }
            }
        }

        //总判断是否符合要求
        if(sub==0&&dif>=3)
        {
            if(len>8)
                printf("OK\n");
            else
                printf("NG\n");
        }
        else
            printf("NG\n");
    }
    return 0;
}

21 简单密码

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

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

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

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

数据范围: 输入的字符串长度满足

本题有多组样例输入
输入描述:
输入包括多个测试数据。输入是一个明文,密码长度不超过100个字符,输入直到文件结尾

输出描述:
输出渊子真正的密文

示例1
输入:
YUANzhi1987

输出:
zvbo9441987
代码

#include <stdio.h>
#include <string.h>
int main()
{
    char pw[100]={'\0'};
    while(scanf("%s\n",&pw)!=EOF)
    {
        int len,i=0;
        len=strlen(pw);
        for(i=0;i<len;i++)
        {
            if(pw[i]>='A'&&pw[i]<='Z')
            {
                if(pw[i]=='Z')
                    pw[i]='a';
                else
                    pw[i]+=33;
            }
            else if(pw[i]>='a'&&pw[i]<='c')
                pw[i]='2';
            else if(pw[i]>='d'&&pw[i]<='f')
                pw[i]='3';
            else if(pw[i]>='g'&&pw[i]<='i')
                pw[i]='4';
            else if(pw[i]>='j'&&pw[i]<='l')
                pw[i]='5';
            else if(pw[i]>='m'&&pw[i]<='o')
                pw[i]='6';
            else if(pw[i]>='p'&&pw[i]<='s')
                pw[i]='7';
            else if(pw[i]>='t'&&pw[i]<='v')
                pw[i]='8';
            else if(pw[i]>='w'&&pw[i]<='z')
                pw[i]='9';
        }
        puts(pw);
    }
    return 0;
}

22 汽水瓶(flag)

描述
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是 5 瓶,方法如下:先用 9 个空瓶子换3瓶汽水,喝掉 3 瓶满的,喝完以后 4 个空瓶子,用 3 个再换一瓶,喝掉这瓶满的,这时候剩 2 个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用 3 个空瓶子换一瓶满的还给老板。如果小张手上有 n 个空汽水瓶,最多可以换多少瓶汽水喝?

数据范围:输入的正整数满足

注意:本题存在多组输入。
允许如题面所述向老板借汽水。
输入的 0 仅表示输入结束,并不用输出结果
输入描述:
输入文件最多包含 10 组测试数据,每个数据占一行,仅包含一个正整数 n( 1<=n<=100 ),表示小张手上的空汽水瓶数。n=0 表示输入结束,你的程序不应当处理这一行。
输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
示例1
输入:
3
10
81
0
输出:
1
5
40

说明:
样例 1 解释:用三个空瓶换一瓶汽水,剩一个空瓶无法继续交换
样例 2 解释:用九个空瓶换三瓶汽水,剩四个空瓶再用三个空瓶换一瓶汽水,剩两个空瓶,向老板借一瓶汽水喝完得三个空瓶换一瓶汽水还给老板
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是 5 瓶,方法如下:先用 9 个空瓶子换3瓶汽水,喝掉 3 瓶满的,喝完以后 4 个空瓶子,用 3 个再换一瓶,喝掉这瓶满的,这时候剩 2 个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用 3 个空瓶子换一瓶满的还给老板。如果小张手上有 n 个空汽水瓶,最多可以换多少瓶汽水喝?

数据范围:输入的正整数满足

注意:本题存在多组输入。
允许如题面所述向老板借汽水。
输入的 0 仅表示输入结束,并不用输出结果
输入描述:
输入文件最多包含 10 组测试数据,每个数据占一行,仅包含一个正整数 n( 1<=n<=100 ),表示小张手上的空汽水瓶数。n=0 表示输入结束,你的程序不应当处理这一行。

输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。

示例1
输入:
3
10
81
0

输出:
1
5
40

说明:
样例 1 解释:用三个空瓶换一瓶汽水,剩一个空瓶无法继续交换
样例 2 解释:用九个空瓶换三瓶汽水,剩四个空瓶再用三个空瓶换一瓶汽水,剩两个空瓶,向老板借一瓶汽水喝完得三个空瓶换一瓶汽水还给老板
代码

#include <stdio.h>
int main(void)
{
    int b,c,n;
    while(scanf("%d",&n)!=EOF){
        b=n;
        if(b>=2){
            c=b/2;
            printf("%d\n",c);
        }
        else{
            printf("\n");
        }
    }
}

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

描述
实现删除字符串中出现次数最少的字符,若多个字符出现次数一样,则都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
注意每个输入文件有多组输入,即多个字符串用回车隔开

数据范围:输入的字符串长度满足 ,保证输入的字符串中仅出现小写字母
输入描述:
字符串只包含小写英文字母, 不考虑非法输入,输入的字符串长度小于等于20个字节。

输出描述:
删除字符串中出现次数最少的字符后的字符串。

示例1
输入:
abcdd
aabcddd

输出:
dd
aaddd

代码

#include <stdio.h>

int main()
{
    char str[20]={'\0'};
    while(scanf("%s\n",&str)!=EOF)
    {
        int len=0;
        int min_cnt,min_aph=0;
        int rc[26]={0}; //记录26个字母出现的次数
        int tmp; //临时存放转换后的字母
        char min_c; //存放出现次数最少的字母
        len=strlen(str);
        int i,j,k=0;
        //记录每个字符出现的次数
        for(i=0;i<len;i++)
        {
            tmp=(int)(str[i]-97);
            rc[tmp]++;
        }
        //找到出现次数最少的字符
        for(i=0;i<26;i++)
        {
            if(rc[i]!=0)
            {
                min_aph=i;
                min_cnt=rc[i];
                break;
            }
         }
        for(i=0;i<26;i++)
        {
            if(rc[i]<min_cnt&&rc[i]!=0)
            {
                  min_aph=i;
                  min_cnt=rc[i];
            }
        }
        min_c=(char)(min_aph+97);
        //删除它
        for(i=0;i<len;i++)
        {
            if(str[i]==min_c)
            {
                for(j=i;j<len;j++)
                {
                    str[j]=str[j+1];
                }
                len--;
            }
        }
        //再次查看是否有相同长度的字符
          for(i=0;i<26;i++)
            {
                if(rc[i]==min_cnt)
                {
                      min_aph=i;
                      min_c=(char)(min_aph+97);
                      for(j=0;j<len;j++)
                      {
                        if(str[j]==min_c)
                        {
                            for(k=j;k<len;k++)
                            {
                                str[k]=str[k+1];
                            }
                            len--;
                        }
                      }
                 }
            }

        //输出删除后的字符串
        puts(str);
    }
    return 0;
}

24 合唱队

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

注意:不允许改变队列元素的先后顺序 且 不要求最高同学左右人数必须相等
请注意处理多组输入输出!

数据范围:

输入描述:
有多组用例,每组都包含两行数据,第一行是同学的总数 N ,第二行是 N 位同学的身高,以空格隔开
输出描述:
最少需要几位同学出列
示例1
输入:
8
186 186 150 200 160 130 197 200

输出:
4

说明:
由于不允许改变队列元素的先后顺序,所以最终剩下的队列应该为186 200 160 130或150 200 160 130

代码

#include<stdio.h>

int max(int a,int b)
{
    return a > b ? a : b;
}

int main()
{
    int n;
    while(EOF != scanf("%d",&n))
    {
        int arr[n];
        for(int i=0;i<n;i++)
            scanf("%d",&arr[i]);
        int dpL[n],dpR[n];
        int dpSum[n];
        for(int i=0;i<n;i++)
        {
            dpL[i]=1;
            dpR[i]=1;
        }
        //-------------------------------------
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(arr[i] > arr[j])
                {
                    dpL[i] = max(dpL[i],dpL[j]+1);
                }
            }
        }
        
        for(int i=n-1;i>=0;i--)
        {
            for(int j=i+1;j<=n-1;j++)
            {
                if(arr[i] > arr[j])
                {
                    dpR[i] = max(dpR[i],dpR[j]+1);
                }
            }
        }
        //--------------------------------------------
        for(int i=0;i<n;i++)
            dpSum[i] = dpL[i] + dpR[i] - 1;
        int count = 0;
        for(int i=0;i<n;i++)
        {
            count = max(count,dpSum[i]);
        }
        printf("%d\n",n-count);
    }
    return 0;
}

25 数据分类处理

描述
信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。

采集输入大数据和分类规则,通过大数据分类处理程序,将大数据分类输出。

请注意本题有多组输入用例。

数据范围: ,输入的整数大小满足
输入描述:
一组输入整数序列I和一组规则整数序列R,I和R序列的第一个整数为序列的个数(个数不包含第一个整数);整数范围为0~(2^31)-1,序列个数不限

输出描述:
从R依次中取出R,对I进行处理,找到满足条件的I:

I整数对应的数字需要连续包含R对应的数字。比如R为23,I为231,那么I包含了R,条件满足 。

按R从小到大的顺序:

(1)先输出R

(2)再输出满足条件的I的个数;

(3)然后输出满足条件的I在I序列中的位置索引(从0开始);

(4)最后再输出I。

附加条件:

(1)R需要从小到大排序。相同的R只需要输出索引小的以及满足条件的I,索引大的需要过滤掉

(2)如果没有满足条件的I,对应的R不用输出

(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)

序列I:15,123,456,786,453,46,7,5,3,665,453456,745,456,786,453,123(第一个15表明后续有15个整数)

序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)

输出:30, 3,6,0,123,3,453,7,3,9,453456,13,453,14,123,6,7,1,456,2,786,4,46,8,665,9,453456,11,456,12,786

说明:

30----后续有30个整数

3----从小到大排序,第一个R为0,但没有满足条件的I,不输出0,而下一个R是3

6— 存在6个包含3的I

0— 123所在的原序号为0

123— 123包含3,满足条件

示例1
输入:
15 123 456 786 453 46 7 5 3 665 453456 745 456 786 453 123
5 6 3 6 3 0

输出:
30 3 6 0 123 3 453 7 3 9 453456 13 453 14 123 6 7 1 456 2 786 4 46 8 665 9 453456 11 456 12 786
代码
就是运行时间比较长,唉。。。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int i,j;
long int temp;
/*删除重复项并排序输出排序后的R数组地址和元素个数。*/
int de_repeat_sort(long int R[],int num2)
{
    long int dp[num2];
    for(i=0;i<num2;i++)
    {
        for(j=0;j<num2-1;j++)
        {
            if(R[j]>R[j+1])
            {
                temp=R[j];
                R[j]=R[j+1];
                R[j+1]=temp;
            }
            if(R[j]==R[j+1])
            {
                R[j+1]=-1;
            }
        }
    }
    j=0;
    for(i=0;i<num2;i++)
    {
        if(R[i]!=-1)
        {
            dp[j]=R[i];
            j++;
        }
    }
    num2=j;
    j=0;
    for(i=0;i<num2;i++)
    {
        R[i]=dp[i];
        j++;
    }
    return num2;
}
int main()
{
    long int I[1000],R[1000];
    int num1,num2,num=0,num3=0;
    char str_R[30],str_I[30];
    while(scanf("%d",&num1)!=EOF)
    {
        for(i=0;i<num1;i++)
        {
            scanf("%ld",&I[i]);
        }
        scanf("%d",&num2);
        for(i=0;i<num2;i++)
        {
            scanf("%ld",&R[i]);
        }
        num2=de_repeat_sort(R,num2);//排序
        /*计算输出的总元素个数。*/
        for(i=0;i<num2;i++)
        {
            sprintf(str_R,"%ld",R[i]);
            for(j=0;j<num1;j++)
            {
                sprintf(str_I,"%ld",I[j]);
                if(strstr(str_I,str_R))
                {
                    num=num+2;
                    num3++;
                }
            }
            if(num3>0)
            {
                num=num+2;
                num3=0;
            }
        }
        printf("%d ",num);//输出总元素个数;
        num=0;
        /*按要求输出各个满足条件的元素。*/
        for(i=0;i<num2;i++)
        {
            sprintf(str_R,"%ld",R[i]);//整形数据打印成字符型数据;
            for(j=0;j<num1;j++)
            {
                sprintf(str_I,"%ld",I[j]);
                if(strstr(str_I,str_R))//字符串是否包含判断;
                {
                    num++;
                }
            }
            if(num>0)
            {
                printf("%ld %d ",R[i],num);
                for(j=0;j<num1;j++)
                {
                    sprintf(str_I,"%ld",I[j]);
                    if(strstr(str_I,str_R))
                    {
                        printf("%d %ld ",j,I[j]);
                    }
                }
                num=0;
            }
        }
        printf("\n");
    }
}

26 字符串排序

描述
编写一个程序,将输入字符串中的字符按如下规则排序。

规则 1 :英文字母从 A 到 Z 排列,不区分大小写。

如,输入: Type 输出: epTy

规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。

如,输入: BabA 输出: aABb

规则 3 :非英文字母的其它字符保持原来的位置。

如,输入: By?e 输出: Be?y

注意有多组测试数据,即输入有多行,每一行单独处理(换行符隔开的表示不同行)

数据范围:输入的字符串长度满足

输入描述:
输入字符串
输出描述:
输出字符串
示例1
输入:
A Famous Saying: Much Ado About Nothing (2012/8).

输出:
A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).

代码

#include <stdio.h>
#include <string.h>

int main()
{
    char StrInput[500];
    char StrInputA[500];
    int StrLen = 0;
    
    while(scanf("%[^\n]s", StrInput) != EOF)
    {
        if(getchar() == '\n')
        {
            StrLen = strlen(StrInput);
            
            //获取所有字母,把原来是字母的地方替换为空,不是字母的地方不变,
            int CharNum = 0;
            for(int i=0; i<StrLen; i++)
            {
                if(((StrInput[i] >= 'A') && (StrInput[i] <= 'Z')) || ((StrInput[i] >= 'a') && (StrInput[i] <= 'z')))
                {
                    StrInputA[CharNum] = StrInput[i]; //记录字母
                    StrInput[i] = -1;
                    CharNum++;
                }
            }
            //查找大写字母,标记

//             printf("only char %s\n", StrInputA);
            //字母排行序,
            char CharTemp;
            for(int i=0; i<CharNum-1; i++)
            {
                for(int j=0; j<CharNum-i-1; j++)
                {
                    if(StrInputA[j] <= 'Z')//如果是大写字母,
                    {
                        if(StrInputA[j+1] <= 'Z')
                        {
                            if(StrInputA[j] > StrInputA[j+1])
                            {
                                CharTemp = StrInputA[j];
                                StrInputA[j] = StrInputA[j+1];
                                StrInputA[j+1] = CharTemp;
                            }
                        }
                        else
                        {
                            if(StrInputA[j]+32 > StrInputA[j+1])
                            {
                                CharTemp = StrInputA[j];
                                StrInputA[j] = StrInputA[j+1];
                                StrInputA[j+1] = CharTemp;
                            }
                        }
                    }
                    else //小写字母
                    {
                         if(StrInputA[j+1] <= 'Z')
                        {
                            if(StrInputA[j] > StrInputA[j+1]+32)
                            {
                                CharTemp = StrInputA[j];
                                StrInputA[j] = StrInputA[j+1];
                                StrInputA[j+1] = CharTemp;
                            }
                        }
                        else
                        {
                            if(StrInputA[j] > StrInputA[j+1])
                            {
                                CharTemp = StrInputA[j];
                                StrInputA[j] = StrInputA[j+1];
                                StrInputA[j+1] = CharTemp;
                            }
                        }
                    }
                }
            }
//             printf("sort char %s\n", StrInputA);
            //将字符插入原字符串
            int j = 0;
            for(int i=0; i<StrLen; i++)
            {
                if(StrInput[i] != -1)
                {
                    continue;
                }
                StrInput[i] = StrInputA[j];
                j++;
            }
            //打印
            printf("%s\n", StrInput);
        }
    }
}
         

27 查找兄弟单词

描述
定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。
兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
现在给定你 n 个单词,另外再给你一个单词 str ,让你寻找 str 的兄弟单词里,按字典序排列后的第 k 个单词是什么?
注意:字典中可能有重复单词。本题含有多组输入数据。

数据范围:,输入的字符串长度满足 ,
输入描述:
先输入单词的个数n,再输入n个单词。 再输入一个单词,为待查找的单词x 最后输入数字k
输出描述:
输出查找到x的兄弟单词的个数m 然后输出查找到的按照字典顺序排序后的第k个兄弟单词,没有符合第k个的话则不用输出。
示例1
输入:
3 abc bca cab abc 1

输出:
2
bca

示例2
输入:
6 cab ad abcd cba abc bca abc 1

输出:
3
bca

说明:
abc的兄弟单词有cab cba bca,所以输出3
经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca

代码

#include "stdio.h"
#include "string.h"

void inorder(unsigned char *p[],unsigned char len)
{
    unsigned char *p_tmp=NULL;
    int i,j;
    for(i=0;i<len-1;i++)
    {
        for(j=i+1;j<len;j++)
        {
            if(strcmp(p[i],p[j])>0)
            {
                p_tmp = p[i];
                p[i] = p[j];
                p[j] = p_tmp;
            }
        }
    }
}

int CheckBrother(unsigned char *p_s1,unsigned char *p_s2)
{
    int len=strlen(p_s1);
    if(strlen(p_s1)==strlen(p_s2) && memcmp(p_s1,p_s2,len)!=0)//数据长度相等,并且不是完全一样的两个字符串
    {
        int i,j;
        unsigned char s2[12]={0};
        unsigned char tmp;
        memcpy(s2,p_s2,len);
        for(i=0;i<len;i++)
        {
            for(j=i;j<len;j++)
            {
                if(p_s1[i]==s2[j])
                {
                    tmp = s2[i];
                    s2[i] = s2[j];
                    s2[j] = tmp;
                    break;
                }
            }
            
            if(j==len)
            {
                return 0;
            }
        }
    }
    else
    {
        return 0;
    }
    return 1;
}

int main()
{
    unsigned char *p_str[1000]={NULL},*p_cur_str=NULL;
    unsigned char str[10000]={0};//1000*10=10000
    unsigned char word[12]={0};
    int i,len,n=0,k,m=0,inx=0,cnt=0;
    gets(str);
    len = strlen(str);
    
    p_cur_str = &str[0];
    for(i=0;i<len;i++)
    {
        if(str[i]==' ')
        {
            str[i]=0;//添加结束符
            if(cnt>0)//检测到有字符
            {
                p_str[inx++]=p_cur_str;
            }
            p_cur_str = &str[i+1];//指向下一个字符串
            cnt=0;
        }
        else
        {
            cnt++;
        }
    }
    if(cnt>0)//检测到有字符
    {
        p_str[inx++]=p_cur_str;
    }
    
    m=0;
    memcpy(word,p_str[inx-2],strlen(p_str[inx-2]));
    for(i=0;i<inx;i++)
    {
        if(i==0)
        {
            n = atoi(p_str[i]);//理论上n+3=inx
        }
        else if(i==inx-2)//待查找的x字符串
        {}
        else if(i==inx-1)//最后一个字符串
        {
            k = atoi(p_str[i]);
            if(k>0)
                k--;//转换成数组下标
        }
        else
        {
            if(CheckBrother(word,p_str[i]))
            {
                p_str[m++]=p_str[i];
            }
        }
    }
    printf("%d\r\n",m);
    if(k<m)
    {
        inorder(p_str,m);
        printf("%s\r\n",p_str[k]);
    }
    
    return 0;
}

28 素数伴侣 (无)

描述

若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。

输入:

有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。

输出:

输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。

数据范围: ,输入的数据大小满足

本题有多组输入
输入描述:
输入说明
1 输入一个正偶数 n
2 输入 n 个整数
题目有多组输入

输出描述:
求得的“最佳方案”组成“素数伴侣”的对数。

示例1
输入:
4
2 5 6 13
2
3 6

输出:
2
0

示例2
输入:
2
3 6

输出:
0
代码

29 字符串加解密

描述
1、对输入的字符串进行加解密,并输出。

2、加密方法为:

当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;

当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;

其他字符不做变化。

3、解密方法为加密的逆过程。

本题含有多组样例输入。

数据范围:输入的两个字符串长度满足 ,保证输入的字符串都是大小写字母或者数字
输入描述:
输入说明
输入一串要加密的密码
输入一串加过密的密码

输出描述:
输出说明
输出加密后的字符
输出解密后的字符

示例1
输入:
abcdefg
BCDEFGH

输出:
BCDEFGH
abcdefg

代码

#include <stdio.h>
#include <ctype.h>
#include <string.h>

void encode(char *ptr)
{
    int len = strlen(ptr);
    for(int i = 0; i < len; i++)
    {
        if(isalpha(ptr[i]))
        {
            if(isupper(ptr[i]))
                ptr[i] = tolower(ptr[i]);
            else
                ptr[i] = toupper(ptr[i]);
            if('z' != tolower(ptr[i]))
                ptr[i]++;
            else
            {
                if(isupper(ptr[i]))
                    ptr[i] = 'A';
                else
                    ptr[i] = 'a';
            }
        }
        else if(isdigit(ptr[i]))
        {
            if('9' != ptr[i])
                ptr[i]++;
            else
                ptr[i] = '0';
        }
    }
}

void decode(char *ptr)
{
    int len = strlen(ptr);
    for(int i = 0; i < len; i++)
    {
        if(isalpha(ptr[i]))
        {
            if(isupper(ptr[i]))
                ptr[i] = tolower(ptr[i]);
            else
                ptr[i] = toupper(ptr[i]);
            if('a' != tolower(ptr[i]))
                ptr[i]--;
            else
            {
                if(isupper(ptr[i]))
                    ptr[i] = 'Z';
                else
                    ptr[i] = 'z';
            }
        }
        else if(isdigit(ptr[i]))
        {
            if('0' != ptr[i])
                ptr[i]--;
            else
                ptr[i] = '9';
        }
    }
}

int main(void)
{
    int i = 0;
    char str[512];
    while(gets(str))
    {
        if(i%2 == 0)
            encode(str);
        else
            decode(str);
        i++;
        printf("%s\n", str);
    }
    return 0;
}

30 字符串合并

描述
按照指定规则对输入的字符串进行处理。

详细描述:

第一步:将输入的两个字符串str1和str2进行前后合并。如给定字符串 “dec” 和字符串 “fab” , 合并后生成的字符串为 “decfab”

第二步:对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标的意思是字符在字符串中的位置。注意排序后在新串中仍需要保持原来的奇偶性。例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符’d’、‘c’、‘a’和下标为奇数的字符’e’、‘f’、'b’进行排序(生成 ‘a’、‘c’、‘d’ 和 ‘b’ 、‘e’ 、‘f’),再依次分别放回原串中的偶数位和奇数位,新字符串变为“abcedf”

第三步:对排序后的字符串中的’0’‘9’、‘A’‘F’和’a’~'f’字符,需要进行转换操作。
转换规则如下:
对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序,然后再转换成对应的十六进制大写字符(注:字符 a~f 的十六进制对应十进制的10~15,大写同理)。
如字符 ‘4’,其二进制为 0100 ,则翻转后为 0010 ,也就是 2 。转换后的字符为 ‘2’。
如字符 ‘7’,其二进制为 0111 ,则翻转后为 1110 ,对应的十进制是14,转换为十六进制的大写字母为 ‘E’。
如字符 ‘C’,代表的十进制是 12 ,其二进制为 1100 ,则翻转后为 0011,也就是3。转换后的字符是 ‘3’。
根据这个转换规则,由第二步生成的字符串 “abcedf” 转换后会生成字符串 “5D37BF”

注意本题含有多组样例输入。

数据范围:输入的字符串长度满足

输入描述:
本题含有多组样例输入。每组样例输入两个字符串,用空格隔开。

输出描述:
输出转化后的结果。每组样例输出一行。

示例1
输入:
dec fab

输出:
5D37BF

示例2
输入:
ab CD

输出:
3B5D

说明:
合并后为abCD,按奇数位和偶数位排序后是CDab(请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D
示例3
输入:
123 15

输出:
88C4A

代码

#include <stdio.h>
#include <ctype.h>
#include <string.h>

void sort(char *ptr)
{
    int len = strlen(ptr);
    for(int i = 0; i < len; i += 2)
    {
        for(int j = i+2; j < len; j += 2)
        {
            if(ptr[i] > ptr[j])
            {
                char ch = ptr[i];
                ptr[i] = ptr[j];
                ptr[j] = ch;
            }
        }
    }
}

unsigned char str2hex(char ch)
{
    if(isdigit(ch))
        return ch - '0';
    else
        return tolower(ch) - 'a' + 10;
}

char hex2str(unsigned char hex)
{
    if(hex < 10)
        return '0' + hex;
    else
        return 'A' + hex - 10;
}

unsigned char convertch(unsigned char ch)
{
    unsigned char ret = 0x00;
    for(int i = 0; i < 4; i++)
    {
        if(ch & 0x1)
            ret |= 0x1;
        ch >>= 1;
        ret <<= 1;
    }
    ret >>= 1;
    return ret;
}

void convert(char *ptr)
{
    int len = strlen(ptr);
    for(int i = 0; i < len; i++)
    {
        if(isxdigit(ptr[i]))
            ptr[i] = hex2str(convertch(str2hex(ptr[i])));
    }
}

int main(void)
{
    int i = 0;
    char str[512], output[1024];
    while(scanf("%s",str) != EOF)
    {
        if(i == 0)
        {
            memset(output, '\0', sizeof(output));
            memcpy(output, str, strlen(str));
            i++;
            continue;
        }
        else
        {
            i = 0;
            strcat(output, str);
            sort(output);
            sort(output+1);
//             printf("%s\n", output);
            convert(output);
            printf("%s\n", output);
        }
    }
    return 0;
}

31 单词倒排

描述
对字符串中的所有单词进行倒排。

说明:

1、构成单词的字符只有26个大写或小写英文字母;

2、非构成单词的字符均视为单词间隔符;

3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

4、每个单词最长20个字母;

数据范围:字符串长度满足
输入描述:
输入一行以空格来分隔的句子

输出描述:
输出句子的逆序

示例1
输入:
I am a student

输出:
student a am I

示例2
输入:
$bo*y gi!r#l

输出:
l r gi y b

代码

#include <stdio.h>
#include <stdlib.h>

int main(){
    char str[100][22];
    int i=0;
    int x;
    while(1){
        x=scanf("%[a-z|A-Z]",str[i]);
        if(getchar()=='\n') break;
        if(x) i++;
    }
    for(int j=i;j>=0;j--){
        printf("%s ",str[j]);
    }
    return 0;
}

或者(by john)

#include <stdio.h>
#include <stdlib.h>
#include<string.h>

int main(){

    char s[100];
    char str[100][100];
    int num = 0;
    int k=0;
    int z=0;    
    
    memset(s,0x0,sizeof(s));
    memset(str,0x0,sizeof(str));
   //scanf("%s",s);
    gets(s);
    
    num = strlen(s);
    //printf("%d\n",num);
    //printf("%s\n",s); 
        for(int i=0;i<=num;i++)
        {
            //printf("%c",s[i]); 
            if((s[i]>='A' && s[i]<='Z')||(s[i]>='a' && s[i]<='z'))
            {
                str[k][z++] = s[i];
                //printf("%c",s[i]);
            } 
            else
            {
                z=0;
                k++;
                //printf("%d\n",k);
                
            }
        }

    printf("%d\n",k);
    //printf("%s",&str[k-1][0]);
        for(int j=k;j>=0;j--)
        {
            printf("%s ",str[j-1]);
        }
    return 0;
}

32 密码截取

描述
Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

数据范围:字符串长度满足
输入描述:
输入一个字符串(字符串的长度不超过2500)

输出描述:
返回有效密码串的最大长度

示例1
输入:
ABBA

输出:
4

示例2
输入:
ABBBA

输出:
5

示例3
输入:
12HHHHA

输出:
4

代码

#include <stdio.h>
#include <string.h>

int odd(char *ptr, int len)
{
    int count = 1;
    char *pl = ptr-1;
    char *pr = ptr+1;
    for(int i = 0; i < len; i++)
    {
        if(*pl != *pr)
            break;
        count += 2;
        pl -= 1;
        pr += 1;
    }
    return count;
}

int even(char *pl, char *pr, len)
{
    int count = 2;
    for(int i = 0; i < len; i++)
    {
        if(*pl != *pr)
            break;
        count += 2;
        pl -= 1;
        pr += 1;
    }
    return count;
}

int secrect(char *ptr, int left, int right)
{
    int len = left > right ? right: left;
    if(len == 0)
        return 1;
    if(*ptr != *(ptr+1))
        return odd(ptr, len);
    int a = odd(ptr, len);
    int b = even(ptr-1, ptr+2, len);
    return a > b ? a : b;
}

int maxlen(int a, b)
{
    return a > b ? a : b;
}

int main(void)
{
    char str[2501];
    while(gets(str))
    {
        int max = 1;
        int len = strlen(str);
        for(int i = 0;i < len; i++)
        {
            max = maxlen(max, secrect(str+i, i, len - i));
        }
        printf("%d\n", max);
    }
    return 0;
}

33 整数与IP地址间的转换

描述
原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字 相对应的二进制数
10 00001010
0 00000000
3 00000011
193 11000001

组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。

本题含有多组输入用例,每组用例需要你将一个ip地址转换为整数、将一个整数转换为ip地址。

数据范围:保证输入的是合法的 IP 序列

输入描述:
输入
1 输入IP地址
2 输入10进制型的IP地址

输出描述:
输出
1 输出转换成10进制的IP地址
2 输出转换后的IP地址

示例1
输入:
10.0.3.193
167969729

输出:
167773121
10.3.3.193

代码

#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[128];
    while(gets(str))
    {
        int is_ip = 0;
        int len = strlen(str);
        for(int i = 0; i < len; i++)
        {
            if(str[i] == '.')
                is_ip = 1;
        }
        if(is_ip)
        {
            unsigned int number = 0;
            unsigned char ip[4];
            sscanf(str, "%d.%d.%d.%d", ip, ip+1, ip+2, ip+3);
            number |= ip[0]<<24;
            number |= ip[1]<<16;
            number |= ip[2]<<8;
            number |= ip[3];
            printf("%u\n", number);
        }
        else
        {
            unsigned int number = 0;
            unsigned char ip[4];
            sscanf(str, "%u", &number);
            ip[0] = number>>24 & 0xFF;
            ip[1] = number>>16 & 0xFF;
            ip[2] = number>>8 & 0xFF;
            ip[3] = number & 0xFF;
            printf("%d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
        }
    }
    return 0;
}

34 图片整理

描述
Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。

本题含有多组样例输入。

数据范围:每组输入的字符串长度满足

输入描述:
Lily使用的图片包括"A"到"Z"、“a"到"z”、“0"到"9”。输入字母或数字个数不超过1024。

输出描述:
Lily的所有图片按照从小到大的顺序输出

示例1
输入:
Ihave1nose2hands10fingers

输出:
0112Iaadeeefghhinnnorsssv

代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char str[1025] = {'\0'};
    while(scanf("%s", str) != EOF)
    {
        int flag[128] = {0};
        char *pstr = str;
        while(*pstr != '\0')
        {
            flag[(int)*pstr] = 1;
            pstr++;
        }
        for(int i=0; i<128; i++)
        {
            if(flag[i])
            {
                pstr = str;
                while(*pstr != '\0')
                {
                    if((int)*pstr == i)
                        printf("%c", *pstr);
                    pstr++;
                }
            }
        }
        printf("\n");
    }
    return 0;
}

35 蛇形矩阵

描述
蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。

例如,当输入5时,应该输出的三角形为:

1 3 6 10 15

2 5 9 14

4 8 13

7 12

11

请注意本题含有多组样例输入。

输入描述:
输入正整数N(N不大于100)

输出描述:
输出一个N行的蛇形矩阵。

示例1
输入:
4

输出:
1 3 6 10
2 5 9
4 8
7

代码

#include <stdio.h>

int main(void)
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        #if 0
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j < n - (i - 1); j++)
            {
                int m = j+i-1;
                printf("%d ", (m * m + m)/2 - (i - 1));
            }
            printf("%d\n", (n * n + n)/2 - (i - 1));
        }
        #else
        int sum = 0;
        int num[100][100] = {0};
        for(int i = 1; i <= n; i++)
        {
            sum += i;
            num[0][i-1] = sum;
        }
        for(int i = 1, k = n - 1; i < n; i++, k--)
        {
            for(int j = 0; j < k; j++)
            {
                num[i][j] = num[i-1][j+1] - 1;
            }
        }
        for(int i = 0, k = n; i < n; i++, k--)
        {
            for(int j = 0; j < k; j++)
            {
                printf("%d ", num[i][j]);
            }
            printf("\n");
        }
        #endif
    }
    return 0;
}

36 字符串加密

描述
有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,将所得结果作为新字母表开头,并将新建立的字母表中未出现的字母按照正常字母表顺序加入新字母表。如下所示:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

T R A I L B Z E S C D F G H J K M N O P Q U V W X Y (实际需建立小写字母的字母表,此字母表仅为方便演示)

上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙, Attack AT DAWN (黎明时攻击)就会被加密为Tpptad TP ITVH。

请实现下述接口,通过指定的密匙和明文得到密文。

本题有多组输入数据。

数据范围: ,保证输入的字符串中仅包含小写字母

输入描述:
先输入key和要加密的字符串

输出描述:
返回加密后的字符串

示例1
输入:
nihao
ni

输出:
le

代码

#include<stdio.h>
#include<string.h>
//Autor:ding
int main()
{
    char mima[30];
    while(scanf("%s",&mima)!=EOF)
    {
        int zifu[26]={0};
        char a[1000];//原文
        scanf("%s",&a);
        int len_a =strlen(a);//得到a的长度
        int len_mima = strlen(mima);
        for(int i = 0;i<len_mima;i++)
        {
            for(int j = i+1;j<len_mima;j++)
            {
                if(mima[j]==mima[i])
                {
                    for(int k =j;k<len_mima-1;k++)
                    {
                        mima[k] = mima[k+1];
                    }
                    len_mima--;
                    j--;
                }
            }
        }//得到符合条件的秘钥
      
      
        char zhuanhuan[26];
        for(int i = 0;i<len_mima;i++)
        {
            zhuanhuan[i] = mima[i];
            if(zhuanhuan[i]-'a'>=0&&zhuanhuan[i]-'a'<=26)//统计字符类型
                zifu[zhuanhuan[i]-'a']++;
            else
                zifu[zhuanhuan[i]-'A']=zifu[zhuanhuan[i]-'A']+2;
        }
        int next_len = len_mima;
        for(int k =0;k<26;k++)
        {
            if(zifu[k]==0)
            {
                zhuanhuan[next_len] = 'a'+k;
                next_len++;
            }
            else if(zifu[k]==1)
            {
                continue;
            }
            else if(zifu[k]==2)
            {
               continue;
            }
        }//得到最新的转换表
      
        for(int i=0;i<len_a;i++)
        {
            if(a[i]>='a'&&a[i]<='z')
            {
                printf("%c",zhuanhuan[a[i]-'a']);
            }
            else
            {
                printf("%c",zhuanhuan[a[i]-'A']);
            }
        }
        printf("\n");//输出加密后的密文
    }//此程序只完成了小写字母加密。
}

37 统计每个月兔子的总数

描述
有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?

本题有多组数据。

数据范围:每组输入满足
输入描述:
多行输入,一行输入一个int型整数表示第n个月

输出描述:
每一行输出对应的兔子总数

示例1
输入:
1
2
3
4
5
9

输出:
1
1
2
3
5
34

代码

#include<stdio.h>
int main()
{
    int mon=1,num=1;
    int a[100];
    a[0]=1;
    a[1]=1;
    while(scanf("%d",&mon)!=EOF){
        if(mon>2){
            for (int i=2;i<mon;i++){
                a[i] = a[i-1]+a[i-2];
                num = a[i];
            }
        }
        else
            num = 1;
        printf("%d\n",num);
    }
}

38 求小球落地5次后所经历的路程和第5次反弹的高度

描述
假设一个球从任意高度自由落下,每次落地后反跳回原高度的一半; 再落下, 求它在第5次落地时,共经历多少米?第5次反弹多高?

最后的误差判断是小数点6位

数据范围:输入的小球初始高度满足 ,且保证是一个整数

输入描述:
输入起始高度,int型

输出描述:
分别输出第5次落地时,共经过多少米第5次反弹多高

示例1
输入:
1

输出:
2.875
0.03125

代码

#include <stdio.h>

int main(){
    float h;                                 //初始高度
    int i;                                   //循环变量
    float ret = 0.0 ;                        //反弹后高度
    float sum = 0.0 ;                        //总路程
    scanf("%a", &h);                         //输入浮点型初始高度

    sum = h ;                                //第一次下落的高度也在总路程中

    for (i=1;i<11;i++){                      //方便技术,循环从1开始,下落5次,合计经过10段路程
        sum = sum + ret;                     //总路程,等于已经过的i段路程,加上本段路程的总和
        if((i%2 != 0) || (i == 1)) {         //第一次下落不需要除以2,之后弹起高度(i为偶数)等于上一次下落高度(i为奇数)的一半
           ret = h / 2.0;
        }else{
            h = ret;                         //下落高度等于上一次弹起高度
        }

    }

   sum = sum - ret;                          //第五次弹起的总路程,要减去第五次下落的路程
    printf("%.3f\n%.5f", sum, ret);          //精度保持在小数点后5位
    return 0;

}

39 判断两个IP是否属于同一子网

描述
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。

示例:
I P 地址  192.168.0.1
子网掩码  255.255.255.0

转化为二进制进行运算:

I P 地址  11000000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000

AND运算 11000000.10101000.00000000.00000000

转化为十进制后为:
192.168.0.0

I P 地址  192.168.0.254
子网掩码  255.255.255.0

转化为二进制进行运算:

I P 地址 11000000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000

AND运算 11000000.10101000.00000000.00000000

转化为十进制后为:
192.168.0.0

通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络。

输入一个子网掩码以及两个ip地址,判断这两个ip地址是否是一个子网络。
若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2。

代码

#include <stdio.h>
#include <string.h>
int change_n(char *str,int *ip,int ty){
    int len,i,j,n=0,l=0,b=1,temp=0;
    int tex;
    len=strlen(str);
    for(i=0;i<len+1;i++){
        
        if((i==len)||(str[i]=='.')){
            for(j=0;j<l;j++){
                temp+=(str[i-1-j]-48)*b;
                b*=10;
            }
            ip[n]=temp;
            n++;
            l=0;
            b=1;
            temp=0;
        }
        else {
            l++;
        }
    }

    if(ty){
        tex=~(ip[0]*256*256*256+ip[1]*256*256+ip[2]*256+ip[3]);
        if((tex&(tex+1))!=0) return 1;
    }
    if((ip[0]>255)||(ip[1]>255)||(ip[2]>255)||(ip[3]>255)||(ip[0]<0)||(ip[1]<0)||(ip[2]<0)||(ip[3]<0)) return 1;
    else return 0;
}

int main(void) { 
	char str0[20],str1[20],str2[20];
	int flag,i,ip[2][4],ip0[4],ip1[4],ip2[4],erro;
	while(scanf("%s",str0)!=-1){
	    erro=0;
	    erro+=change_n(str0,ip0,1);
	    scanf("%s",str1);
	    erro+=change_n(str1,ip1,0);
	    scanf("%s",str2);
	    erro+=change_n(str2,ip2,0);
	    if (erro) {
	        printf("1\n");
	    }
	    else{
    	    flag=1;
    	    for(i=0;i<4;i++){
    	        ip[0][i]=ip0[i]&ip1[i];
    	        ip[1][i]=ip0[i]&ip2[i];
    	        if(ip[0][i]!=ip[1][i]) flag=0;
    	    }
    	    if(flag) printf("0\n");
    	    else printf("2\n");
	    }
	}
}

40 统计字符

描述
输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数。

本题包含多组输入。

数据范围:输入的字符串长度满足

输入描述:
输入一行字符串,可以有空格

输出描述:
统计其中英文字符,空格字符,数字字符,其他字符的个数

示例1
输入:
1qazxsw23 edcvfr45tgbn hy67uj m,ki89ol.\/;p0-=\][

输出:
26
3
10
12

代码

#include<iostream>
#include<string>

using namespace std;

int main(){
    string str;
    int num_e,num_w,num_n,num_o;//英文字母、空格、数字、其他字符的数量
    num_e=num_w=num_n=num_o=0;
    while(getline(cin,str))//逐行统计
    {
        num_e=num_w=num_n=num_o=0;//每从新的一行开始统计的时候都要清零
        for(int i=0;i<str.size();i++){
            if(str[i]>='0'&&str[i]<='9'){//数字
                num_n++;
            }else if((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')){//英文字母
                num_e++;
            }else if(str[i]==' '){//空格
                num_w++;
            }else num_o++;//其他字符
        }
        cout<<num_e<<endl<<num_w<<endl<<num_n<<endl<<num_o<<endl;
    }
    return 0;
}

41 蛇形矩阵

描述

代码

42 称砝码

描述
现有一组砝码,重量互不相等,分别为 m1,m2,m3…mn ;
每种砝码对应的数量为 x1,x2,x3…xn 。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。

注:

称重重量包括 0

本题有多组输入

数据范围:每组输入数据满足 , ,
输入描述:
输入包含多组测试数据。
对于每组测试数据:
第一行:n — 砝码数(范围[1,10])
第二行:m1 m2 m3 … mn — 每个砝码的重量(范围[1,2000])
第三行:x1 x2 x3 … xn — 每个砝码的数量(范围[1,6])
输出描述:
利用给定的砝码可以称出的不同的重量数

示例1
输入:
2
1 2
2 1
10
4 185 35 191 26 148 149 3 172 147
3 5 2 1 5 5 3 1 4 2

输出:
5
3375

代码

#include <stdio.h>
#include <malloc.h>

int main(void)
{
    int cnt;
    int *weight;
    int *num;
    int i, j, k;
    int total;
    char *map;

    while(scanf("%d", &cnt) != EOF)
    {
        total = 1;
        weight = (int* )calloc(cnt, sizeof(int));
        num = (int *)calloc(cnt, sizeof(int));
        for(i=0; i<cnt; i++)
        {
            scanf("%d", weight+i);
        }
        for(i=0; i<cnt; i++)
        {
            scanf("%d", num+i);
            total = total+(*(num+i))*weight[i];
        }

        map = (char* )calloc(total, sizeof(char));
        map[0] = 1;

        for(i=0; i<cnt; i++)
        {
            for(j=0; j<num[i]; j++)
            {
                // 注意从后往前,从前面开始可能会污染后面的原生环境
                for(k=total-1; k>=0; k--)
                {
                    if(map[k])
                    {
                        map[k+weight[i]] = 1;
                    }
                }
            }
        }
        j = 0;
        for(i=0; i<total; i++)
        {
            j = j+map[i];
        }
        printf("%d\n", j);
        free(map);
        free(weight);
        free(num);
    }
    return 0;
}

43 学英语

描述
Jessi初学英语,为了快速读出一串数字,编写程序将数字转换成英文:

具体规则如下:
1.在英语读法中三位数字看成一整体,后面再加一个计数单位。从最右边往左数,三位一单位,例如12,345 等
2.每三位数后记得带上计数单位 分别是thousand, million, billion.
3.公式:百万以下千以上的数 X thousand X, 10亿以下百万以上的数:X million X thousand X, 10 亿以上的数:X billion X million X thousand X. 每个X分别代表三位数或两位数或一位数。
4.在英式英语中百位数和十位数之间要加and,美式英语中则会省略,我们这个题目采用加上and,百分位为零的话,这道题目我们省略and

下面再看几个数字例句:
22: twenty two
100: one hundred
145: one hundred and forty five
1,234: one thousand two hundred and thirty four
8,088: eight thousand (and) eighty eight (注:这个and可加可不加,这个题目我们选择不加)
486,669: four hundred and eighty six thousand six hundred and sixty nine
1,652,510: one million six hundred and fifty two thousand five hundred and ten

说明:
数字为正整数,不考虑小数,转化结果为英文小写;
保证输入的数据合法
关键字提示:and,billion,million,thousand,hundred。

数据范围:

本题含有多组输入数据。

输入描述:
输入多行long型整数

输出描述:
输出相应的英文写法

示例1
输入:
22
100
145
1234
8088
486669
1652510

输出:
twenty two
one hundred
one hundred and forty five
one thousand two hundred and thirty four
eight thousand eighty eight
four hundred and eighty six thousand six hundred and sixty nine
one million six hundred and fifty two thousand five hundred and ten

代码(c++)

#include <iostream>
#include <string>

using namespace std;

const string ones[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
const string tens[] = { "ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen" };
const string twenties[] = { "zero","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety" };
const int ihundreds[] = { (int)1e2, (int)1e3, (int)1e6, (int)1e9, (int)1e12 };
const string hundreds[] = { "hundred", "thousand", "million", "billion" };

string itoe(long long n){
    if (0<=n && n<=9){//个位数,直接输出
        return ones[n];
    }
    if (10<=n && n<20){//十位数,直接输出
        return tens[n%10];
    }
    if (20<=n && n<1e2){//20-100
        return twenties[n/10] + (n%10 ? " " + ones[n%10] : "");
    }
    for (int i=0; i < 4; i++){//大于100
        if (n < ihundreds[i+1]) {//确定范围
            return itoe(n/ihundreds[i]) + " " + hundreds[i] + (n%ihundreds[i] ? (i ? " ": " and ") + itoe(n%ihundreds[i]) : "");//递归转换
        }
    }
    return "";
}

int main(){
    long long n;
    while (cin>>n){
        cout<<itoe(n)<<endl;
    }
    return 0;
}

44 迷宫问题

描述
定义一个二维数组 N*M ,如 5 × 5 数组下所示:

int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。

本题含有多组数据。

数据范围: , 输入的内容只包含

输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述:
左上角到右下角的最短路径,格式如样例所示。

示例1
输入:
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出:
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)

示例2
输入:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0

输出:
(0,0)
(1,0)
(2,0)
(3,0)
(4,0)
(4,1)
(4,2)
(4,3)
(4,4)

说明:
注意:不能斜着走!!

代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void DFS(int** maze,int** vis,int** stack,int m,int n,int i,int j,int top){

    if(i==m-1&&j==n-1) {
        stack[top][0]=i; stack[top][1]=j; 
        for(int i=0;i<=top;i++){
            printf("(%d,%d)\n",stack[i][0],stack[i][1]);
        }
        return;
    }
    else if(i>=m||j>=n||i<0||j<0||vis[i][j]==1||maze[i][j]==1) return;
    else{
        vis[i][j]=1; 
        stack[top][0]=i; stack[top][1]=j;
        top++;
        DFS(maze,vis,stack,m,n,i+1,j,top);
        DFS(maze,vis,stack,m,n,i,j+1,top);
        DFS(maze,vis,stack,m,n,i-1,j,top);
        DFS(maze,vis,stack,m,n,i,j-1,top);
        top--; 
        vis[i][j]=0; 
    }
}

int main(void){
    int i,j,m,n;
    while(scanf("%d %d",&m,&n)!=EOF){
        //输入
        int** vis=(int**)malloc(sizeof(int*)*m);
        int** maze=(int**)malloc(sizeof(int*)*m);

        for(i=0;i<m;i++){
            vis[i]=(int*)malloc(sizeof(int)*n);
            maze[i]=(int*)malloc(sizeof(int)*n);
            memset(vis[i],0,sizeof(int)*n);
            memset(maze[i],0,sizeof(int)*n);
        }
        int** stack=(int**)malloc(sizeof(int*)*(m*n));
        for(i=0;i<m*n;i++){
            stack[i]=(int*)malloc(sizeof(int)*2);
            memset(stack[i],0,sizeof(int)*2);
        }

        for(i=0;i<m;i++){
            for(j=0;j<n;j++){
                scanf("%d",&maze[i][j]);
            }
        }
        //遍历 结果在DFS中输出
        int top=0;
        DFS(maze,vis,stack,m,n,0,0,top);

    }
}

45 Sudoku

描述
问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。
例如:
输入

输出

数据范围:输入一个 9*9 的矩阵
输入描述:
包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:
完整的9X9盘面数组

示例1
输入:
0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1

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

代码(c++)

#include<iostream>
#include<set>
using namespace std;
int flag=0;//是否到了最后一个点
void func(int *a,int i=0,int j=0)
{//三个参数为 数组、当前位置坐标
    if(i>=9||j>=9)//整个数组遍历完,就代表成功了
    {             //但是之后循环还在继续,所以需要一个标记
        flag=1;
        return;
    }
    if(*(a+9*i+j)==0)//如果当前数为零
    {
        set<int> s;//储存当前数不能使用的数
        for(int m=i/3*3;m<i/3*3+3;m++)//找出3*3方格中出现的数
        {
            for(int n=j/3*3;n<j/3*3+3;n++)
            {
                s.insert(*(a+9*m+n));
            }
        }
        for(int m=0,n=0;m<9,n<9;m++,n++)//找出行列中出现的数
        {
            s.insert(*(a+9*i+m));
            s.insert(*(a+9*n+j));
        }
        for(int m=1;m<10;m++)//从1到9,依次试着放进数组中
        {   //如果数组没有遍历完 且没有找到m,说明m可用
            if(flag==0&&s.find(m)==s.end())
            {
                *(a+9*i+j)=m;//赋值
                func(a,i+j/8,(j+1)%9);//递归到下一个点
            }  
        }
        if(flag==0)//如果运行到这里说明前面试错了或者遍历完了整个数组
        {          //用flag排除后一种可能,试错了则会回溯
            *(a+9*i+j)=0;//j将当前值重新赋值为零
            return;
        }
    }
    else func(a,i+j/8,(j+1)%9);//如果当前点不为零,直接到下一个点
}
int main()
{
    int a[9][9];
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
        {
            cin>>a[i][j];
        }
    }
    func((int*)a,0,0);
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<8;j++)
        {
            cout<<a[i][j]<<' ';
        }
        cout<<a[i][8]<<endl;
    }
}

46 名字的漂亮度

描述
给出一个名字,该名字有26个字符组成,定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。
每个字母都有一个“漂亮度”,范围在1到26之间。没有任何两个不同字母拥有相同的“漂亮度”。字母忽略大小写。

给出多个名字,计算每个名字最大可能的“漂亮度”。

本题含有多组数据。

数据范围:输入的名字长度满足

输入描述:
整数N,后续N个名字

输出描述:
每个名称可能的最大漂亮程度

示例1
输入:
2
zhangsan
lisi

输出:
192
101

代码

#include "stdio.h"

int main(){
    int n;
    while(scanf("%d", &n) != EOF){
        char str[n][100000];
        for(int i = 0; i < n; i++){
            scanf("%s", &str[i]);
            int len = strlen(str[i]);
            int ch[26] = {0};
            for(int j = 0; j < len; j++){
                int index = str[i][j] - 'a';
                ch[index]++;
            }
            for(int j = 1; j < 26; j++){
                for(int k = 0; k < 26-j; k++){
                    if(ch[k] < ch[k+1]){
                        int temp = ch[k];
                        ch[k] = ch[k+1];
                        ch[k+1] = temp;
                    }
                }
            }
            int result = 0, weight = 26;
            for(int j = 0; j < 26; j++){
                result += ch[j] * weight--;
            }
            printf("%d\n", result);
        }
    }
    return 0;
}

47 截取字符串

描述

输入一个字符串和一个整数 k ,截取字符串的前k个字符并输出

本题输入含有多组数据

数据范围:字符串长度满足 ,
输入描述:
1.输入待截取的字符串

2.输入一个正整数k,代表截取的长度

输出描述:
截取后的字符串

示例1
输入:
abABCcDEF
6

输出:
abABCc

示例2
输入:
ffIKEHauv
1
bdxPKBhih
6

输出:
f
bdxPKB
代码

#include <stdio.h>
#include <string.h>
int main(void)
{
    char a[1000];
    while(scanf("%s",a)!=EOF)
    {
        int n;
        scanf("%d",&n);
        int i,len;
        len=strlen(a);
        for(i=0;i<n;i++)
        {
            printf("%c",a[i]);
        }
        printf("\n");
        for(i=0;i<len;i++)
        {
            a[i]=0;
        }
    }
}

48 从单向链表中删除指定值的节点

描述
输入一个单向链表和一个节点的值,从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。

链表的值不能重复。

构造过程,例如输入一行数据为:
6 2 1 2 3 2 5 1 4 5 7 2 2
则第一个参数6表示输入总共6个节点,第二个参数2表示头节点值为2,剩下的2个一组表示第2个节点值后面插入第1个节点值,为以下表示:
1 2 表示为
2->1
链表为2->1

3 2表示为
2->3
链表为2->3->1

5 1表示为
1->5
链表为2->3->1->5

4 5表示为
5->4
链表为2->3->1->5->4

7 2表示为
2->7
链表为2->7->3->1->5->4

最后的链表的顺序为 2 7 3 1 5 4

最后一个参数为2,表示要删掉节点为2的值
删除 结点 2

则结果为 7 3 1 5 4

数据范围:链表长度满足 ,节点中的值满足

测试用例保证输入合法

输入描述:
输入一行,有以下4个部分:
1 输入链表结点个数
2 输入头结点的值
3 按照格式插入各个结点
4 输入要删除的结点的值

输出描述:
输出一行
输出删除结点后的序列,每个数后都要加空格

示例1
输入:
5 2 3 2 4 3 5 2 1 4 3

输出:
2 5 4 1

说明:
形成的链表为2->5->3->4->1
删掉节点3,返回的就是2->5->4->1
示例2
输入:
6 2 1 2 3 2 5 1 4 5 7 2 2

输出:
7 3 1 5 4

代码

// 沒看到有c的,我来发一个吧
// 由于是刷题,malloc、scanf等没判断返回值,见谅

#include <stdio.h>
#include <stdlib.h>

typedef struct tagNode {
    int val;
    struct tagNode *next;
} Node;

static void insertNode(Node *head, int aim, int val) {
    while(head != NULL) {
        if(head->val == aim) {
            Node *temp = (Node*)malloc(sizeof(Node));
            temp->val = val;
            temp->next = head->next;
            head->next = temp;
            return;
        }
        head = head->next;
    }
}

static void delNode(Node **head, int aim)
{
    if ((*head)->val == aim) {
        Node *temp = (*head)->next;
        free(*head);
        *head = temp;
        return;
    }
    Node *iter = *head;
    while (iter->next != NULL) {
        if (iter->next->val == aim) {
            Node *temp = iter->next;
            iter->next = temp->next;
            free(temp);
            return;
        }
        iter = iter->next;
    }
}

static void printList(Node *head) {
    while(head != NULL) {
        printf("%d ", head->val);
        head = head->next;
    }
    printf("\n");
}

static void freeList(Node *head) {
    while(head != NULL){
        Node *next = head->next;
        free(head);
        head = next;
    }
}

int main() {
    int num = 0;
    int headVal = 0;
    int delVal = 0;
    scanf("%d %d", &num, &headVal);
    Node *head = (Node*)malloc(sizeof(Node));
    head->next = NULL;
    head->val = headVal;
    int i;
    for (i = 1; i < num; i++) {
        int aim = 0;
        int val = 0;
        scanf("%d %d", &val, &aim);
        insertNode(head, aim, val);
    }
    scanf("%d", &delVal);
    delNode(&head, delVal);
    printList(head);
    freeList(head);
    return 0;
}

52 四则运算

描述
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

数据范围:表达式计算结果和过程中满足 ,字符串长度满足
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
示例1
输入:
3+2*{1+2*[-4/(8-6)+7]}

输出:
25
代码

#include <stdio.h>

short compute(short num1, short num2, char op)
{
    short answer;
    switch(op)
    {
        case '+':
            answer = num1 + num2;
            break;
        case '-':
            answer = num1 - num2;
            break;
        case '*':
            answer = num1 * num2;
            break;
        case '/':
            answer = num1 / num2;
            break;
    }
    return answer;
}

int main(void)
{
    char str[1001]={0};
    char s_stack[1001]={0};
    short n_stack[1001]={0};
    short si=0, ni=0, i=0;
    short temp, num1, num2;
    
    fgets(str, 1001, stdin);
    while(str[i] != '\n' && str[i] != '\0')
    {
        while(str[i] == '(' || str[i] == '[' || str[i] == '{')
        {
            s_stack[si++] = str[i];
            i++;
        }
        if(str[i] == '-')
        {
            if(i==0 || str[i-1]=='(' || str[i-1]=='[' || str[i-1]=='{') // 代表负号
            {
                temp=0;
                i++;
                while(str[i]>='0' && str[i]<='9')
                {
                    temp = temp*10 + str[i] - '0';
                    i++;
                }
                n_stack[ni++] = 0-temp;
            }
            else // 代表减号
            {
                while(si>0 && (s_stack[si-1] == '-' || s_stack[si-1] == '*' || s_stack[si-1] == '/'))
                {
                    num2 = n_stack[--ni];
                    num1 = n_stack[--ni];
                    n_stack[ni++] = compute(num1, num2, s_stack[--si]);
                }
                s_stack[si++] = '-';
                i++;
            }
        }
        if(str[i] == '+')
        {
            if(i==0 || str[i-1]=='(' || str[i-1]=='[' || str[i-1]=='{') //代表正号,直接忽略
                i++;
            else // 代表加号
            {
                while(si>0 && (s_stack[si-1] == '-' || s_stack[si-1] == '*' || s_stack[si-1] == '/'))
                {
                    num2 = n_stack[--ni];
                    num1 = n_stack[--ni];
                    n_stack[ni++] = compute(num1, num2, s_stack[--si]);
                }
                s_stack[si++] = '+';
                i++;
            }
        }
        if(str[i] == '*')
        {
            while(si>0 && s_stack[si-1] == '/')
            {
                num2 = n_stack[--ni];
                num1 = n_stack[--ni];
                n_stack[ni++] = compute(num1, num2, s_stack[--si]);
            }
            s_stack[si++] = '*';
            i++;
        }
        if(str[i] == '/')
        {
            while(si>0 && s_stack[si-1] == '/')
            {
                num2 = n_stack[--ni];
                num1 = n_stack[--ni];
                n_stack[ni++] = compute(num1, num2, s_stack[--si]);
            }
            s_stack[si++] = '/';
            i++;
        }
        if(str[i]>='0' && str[i]<='9')
        {
            temp=0;
            while(str[i]>='0' && str[i]<='9')
            {
                temp = temp*10 + str[i] - '0';
                i++;
            }
            n_stack[ni++] = temp;
        }
        if(str[i] == ')')
        {
            while(s_stack[si-1] != '(')
            {
                num2 = n_stack[--ni];
                num1 = n_stack[--ni];
                n_stack[ni++] = compute(num1, num2, s_stack[--si]);
            }
            si--;
            i++;
        }
        if(str[i] == ']')
        {
            while(s_stack[si-1] != '[')
            {
                num2 = n_stack[--ni];
                num1 = n_stack[--ni];
                n_stack[ni++] = compute(num1, num2, s_stack[--si]);
            }
            si--;
            i++;
        }
        if(str[i] == '}')
        {
            while(s_stack[si-1] != '{')
            {
                num2 = n_stack[--ni];
                num1 = n_stack[--ni];
                n_stack[ni++] = compute(num1, num2, s_stack[--si]);
            }
            si--;
            i++;
        }
    }
    while(si>0)
    {
        num2 = n_stack[--ni];
        num1 = n_stack[--ni];
        n_stack[ni++] = compute(num1, num2, s_stack[--si]);
    }
    printf("%d", n_stack[--ni]);
    return 0;
}

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

描述
输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针。

链表结点定义如下:

struct ListNode

{
int m_nKey;
ListNode* m_pNext;
};
正常返回倒数第k个结点指针,异常返回空指针
数据范围:链表长度满足 , ,链表中数据满足
本题有多组样例输入。
输入描述:
输入说明
1 输入链表结点个数
2 输入链表的值
3 输入k的值

输出描述:
输出一个整数

示例1
输入:
8
1 2 3 4 5 6 7 8
4

输出:
5

代码
这题之所以不难应该是因为单链表逆序找值刚刚好用头插法就是逆序的。
我的c语言回答的。一开始碰到一个问题是什么栈超出、后发现是位置超过链表长度的情况没有写(我的if改成while就好了。)

#include<stdio.h>
#include<malloc.h>

typedef struct Node{
	
	int data;
	struct Node* next;
}NodeList, * pNodeList;

void fun(int n)
{
		int i=0,data=0,targetIndex;
	pNodeList head = (pNodeList)malloc(sizeof(NodeList));
	head->next = NULL;
	for(i=0;i<n;i++)
	{
		pNodeList new = (pNodeList)malloc(sizeof(NodeList));
		
		scanf("%d",&new->data);
		new->next = head->next;
		head->next = new;
				
		
	}
	scanf("%d",&targetIndex);
	
		pNodeList arrow = head;
		if(targetIndex>n){}
		else{
		
		for(i=0;i<targetIndex;i++)
		{
			arrow= arrow->next;	
		}	
		if(arrow->next !=NULL)
		{
		
		printf("%d\n",arrow->data);
	
	}
		
	}
		
}


void main()
{

	
	
int n;
	
	while(scanf("%d\n",&n)!=EOF)
	
	 fun(n);
	system("pause");
}

54 计算字符串的距离

描述
Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。编辑距离的算法是首先由俄国科学家 Levenshtein 提出的,故又叫 Levenshtein Distance 。
Ex:
字符串A: abcdefg
字符串B: abcdef
通过增加或是删掉字符 ”g” 的方式达到目的。这两种方案都需要一次操作。把这个操作所需要的次数定义为两个字符串的距离。
要求:
给定任意两个字符串,写出一个算法计算它们的编辑距离。

数据范围:给定的字符串长度满足

本题含有多组输入数据。
输入描述:
每组用例一共2行,为输入的两个字符串
输出描述:
每组用例输出一行,代表字符串的距离
示例1
输入:
abcdefg
abcdef
abcde
abcdf
abcde
bcdef

输出
1
1
2
代码

#include <string.h>

int min(int a ,int b)
{
    return ((a)>(b)?(b):(a));
}

int get_diff2(char* s1, char* s2)
{
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int *dp = (int*)malloc(sizeof(int*)*(len2+1));
    int *dp2 = (int*)malloc(sizeof(int*)*(len2+1));
    int i,j;
    int tmp1,tmp2,tmp3;
    
    if(*s1=='\0')
        return strlen(s2);
    if(*s2=='\0')
        return strlen(s1);
    
    dp[0]=0;
    for (j=1; j<=len2; j++) 
    {
        dp[j] = j;
    }

    for (i=1; i<=len1; i++)
    {
        dp2[0]=i;
        for(j=1; j<=len2; j++)
        {
            tmp1 = dp[j] +1,tmp2 = dp2[j-1]+1,tmp3 = dp[j-1];
            if(s1[i-1]!=s2[j-1]) tmp3+=1;
            dp2[j] = min(min(tmp1,tmp2),tmp3);
            
            if(j==2)
            {
                dp[0]=i;
                dp[j-1] = dp2[j-1];
            }
            else if(j>=2)
                dp[j-1] = dp2[j-1];
        }
        dp[j-1] = dp2[j-1];
        
    }
    return dp[len2];
}

int main(){
    
    char A[501];
    char B[501];
    int num;
    while(gets(A)&&gets(B))
    {
        
        num = get_diff2(A,B);
        printf("%d\n",num);
    }
    return 0;
    
}

55 杨辉三角的变形

描述

以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数,左上角数到右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。

求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3。

数据范围:

本题有多组输入数据
输入描述:
输入一个int整数

输出描述:
输出返回的int值

示例1
输入:
4
2

输出:
3
-1
代码
//题解,根据规律可发现,偶数出现的位置分别是:-1 -1 2 3 2 4 2 3 2 4 循环往复

#include<stdio.h>
int main(){
    int n,m,a[4] = {2,3,2,4};
    while(scanf("%d",&n)!=EOF){
        if(n <= 2){
            m = -1;
        }else{
            n -= 3;
            n %= 4; 
            m = a[n];
        }
        printf("%d\n",m);
    }
    return 0;
}

56 表达式求值

描述
给定一个字符串描述的算术表达式,计算出结果值。

输入字符串长度不超过 100 ,合法的字符包括 ”+, -, *, /, (, )” , ”0-9” 。

数据范围:运算过程中和最终结果均满足 ,即只进行整型运算,确保输入的表达式合法
输入描述:
输入算术表达式

输出描述:
计算出结果值

示例1
输入:
400+5

输出:
405

代码(c++)

#include<iostream>
#include<stack>
using namespace std;
int pos;
int result(const string& data)
{
    int num=0;
    char flag = '+';
    stack<int> stk;
    int len = data.length();
    while(pos<len)
    {
        if(data[pos] == '(')
        {
            pos++;
            num = result(data);
        }
        while(pos<len && isdigit(data[pos]))
        {
            num =num*10+ data[pos] - '0';
            pos ++;
        }
        switch(flag)
        {
            case '+':
            {
                stk.push(num);
                break;
            }
            case '-':
            {
                stk.push(-num);
                break;
            }
            case '*':
            {
                stk.top() *= num;
                break;
            }
            case '/':
            {
                stk.top() /= num;
                break;
            }
        }
        num = 0;
        flag = data[pos];
        if(data[pos] == ')')
        {
            ++pos;
            break;
        }
        ++pos;
    }
    int sum = 0;
    while(!stk.empty())
    {
        sum += stk.top();
        stk.pop();
    }
    return sum;
}
int main()
{
    string str;
    cin>>str;
    pos = 0;
    cout<<result(str);
    return 0;
}

57 挑7

描述
输出小于等于 n 的与 7 有关数字的个数,包括 7 的倍数,还有包含 7 的数字(如 17 ,27 ,37 … 70 ,71 ,72 ,73…)的个数(一组测试用例里可能有多组数据,请注意处理)

数据范围:

本题有多组输入
输入描述:
多组输入每组输入 1 个正整数 n 。( n 不大于 30000 )

输出描述:
不大于n的与7有关的数字个数,例如输入20,与7有关的数字包括7,14,17.

示例1
输入:
20
10

输出:
3
1

代码

#include <stdio.h>
int main(void)
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int i,m,b;
        int cnt=0;
        for(i=1;i<=n;i++)
        {
            m=i;
            while(m)
            {
                b=m%10;
                m=m/10;
                if(b==7||m==7||i%7==0){
                    cnt++;
                    break;
                }
            }
        }
        printf("%d\n",cnt);
    }
}

58 完全数计算

描述

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。
它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

输入n,请输出n以内(含n)完全数的个数。

数据范围:

本题输入含有多组样例。
输入描述:
输入一个数字n
输出描述:
输出不超过n的完全数的个数
示例1
输入:
1000
7
100

输出:
3
1
2
代码

#include<stdio.h>

int main(int argc, char const *argv[])
{
    int n = 0, sum = 0, number = 0;
    while (scanf("%d", &n) != EOF)
    {

        number = 0;
        for (int k = 6; k <= n; k++)
        {
            sum = 0;
            for (int i = 1; i <= k/2; i++)
            {
                if (k%i == 0)
                {
                    sum += i;
                }
            }
            if (sum == k)
            {
                number++;
            }
        }
        printf("%d\n", number);
    }

    return 0;
}

59 高精度整数加法

描述
输入两个用字符串 str 表示的整数,求它们所表示的数之和。

本题含有多组样例输入。

数据范围:
输入描述:
输入两个字符串。保证字符串只含有’0’~'9’字符
输出描述:
输出求和后的结果

示例1
输入:
9876543210
1234567890

输出:
11111111100
代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char str1[10000],str2[10000],num[10000];
    int i,len,lenmax,wei,len1,len2,jinwei,temp;
while(scanf("%s",str1)!=-1)
{
        scanf("%s",str2);
        jinwei=0;
        len1=strlen(str1);
        len2=strlen(str2);
        lenmax=(len1>len2)?len1:len2;
        if((len1==lenmax)&&(len1!=len2))
{
            memcpy(str2+lenmax-len2,str2,len2);
            memset(str2,'0',lenmax-len2);
        }
        else if((len2==lenmax)&&(len1!=len2))
{
            memcpy(str1+lenmax-len1,str1,len1);
            memset(str1,'0',lenmax-len1);
        }

        
        len=lenmax;
        for(i=0;i<lenmax;i++){
            temp=str1[lenmax-1-i]-48+str2[lenmax-1-i]-48+jinwei;
            if(temp>=10) {
                temp-=10;
                jinwei=1;
            }
            else
 jinwei=0;
            num[i]=temp;
            
            if(((i==(lenmax-1))&&(jinwei==1))){
                num[i+1]=1;
                len=lenmax+1;
            }
        }
        for(i=0;i<len;i++){
            printf("%d",num[len-1-i]);
        }
        printf("\n");
    }
    
    
    return 0;
}

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

描述
输入n个整数,输出其中最小的k个整数并按升序输出

本题有多组输入样例

数据范围: ,输入的整数满足
输入描述:
第一行输入两个整数n和k
第二行输入一个整数数组

输出描述:
输出一个从小到大排序的整数数组

示例1
输入:
5 2
1 3 5 7 2

输出:
1 2

代码

#include<stdio.h>
#include<stdlib.h>

int cmpFun(int* a,int* b)
{
    return *a - *b;
}

int main()
{
    int n,k;
    int arr[1000];
    int i,j;
    while(EOF != scanf("%d%d",&n,&k))
    {
        for(i=0;i<n;i++)
        {
            scanf("%d",&arr[i]);
        }
        qsort(arr, n, sizeof(int), cmpFun);
        for(i=0;i<k;i++)
        {
            if(i<k-1)printf("%d ",arr[i]);
            else printf("%d",arr[i]);
        }
        printf("\n");
    }
    
    return 0;
}

61 找出字符串中第一个只出现一次的字符

描述
找出字符串中第一个只出现一次的字符

数据范围:输入的字符串长度满足

输入描述:
输入几个非空字符串

输出描述:
输出第一个只出现一次的字符,如果不存在输出-1

示例1
输入:
asdfasdfo
aabb

输出:
o
-1

代码

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char str[500];
    while(scanf("%s", str) != EOF)
    {
        int len=strlen(str);
        int hash_table[128] = {0};
        for(int i=0; i<len; i++)
        {
            hash_table[str[i]]++;
        }
        int flag=0;
        for(int i=0; i<len; i++)
        {
            if(hash_table[str[i]] == 1)
            {
                printf("%c\n", str[i]);
                flag = 1;
                break;
            }
        }
        if(!flag) printf("-1\n");
    }
    return 0;
}

62 查找组成一个偶数最接近的两个素数

描述
任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。

本题含有多组样例输入。

数据范围:输入的数据满足
输入描述:
输入一个大于2的偶数

输出描述:
输出两个素数

示例1
输入:
20

输出:
7
13

示例2
输入:
4

输出:
2
2

代码

#include <stdio.h>
int main(void)
{
    int n;
    int a[100];
    while(scanf("%d",&n)!=EOF)
    {
        int i,j,k=0,cnt=0;
        int diff,min=10000;
        int index,index1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=i;j++)
            {
                if(i%j==0){
                    cnt++;
                }
            }
            if(cnt==2){
                    a[k]=i;
                    k++;
            }
            cnt=0;
        }
        for(i=0;i<k;i++)
        {
            for(j=0;j<k;j++)
            {
                if(a[i]+a[j]==n&&a[j]>=a[i])
                {
                    diff=a[j]-a[i];
                    if(diff<min){
                        min=diff;
                        index=a[i];
                        index1=a[j];
                    }
                }
            }
        }
        printf("%d\n%d",index,index1);
        printf("\n");
    }
}

63 放苹果

描述
把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

数据范围:,。

本题含有多组样例输入。

输入描述:
输入两个int整数

输出描述:
输出结果,int型

示例1
输入:
7 3

输出:
8
代码

#include <stdio.h>

int f(int m,int n){
    if ((m==0)||(n==1)) return 1;
    else if(m<n) return f(m,m);
    return(f(m-n,n)+f(m,n-1));
}

int main(void) { 
    int m,n;
    while(scanf("%d",&m)!=-1){
        scanf("%d",&n);
        printf("%d\n",f(m,n));
    }
	return 0;
}

64 查找输入整数二进制中1的个数

描述
输入一个正整数,计算它在二进制下的1的个数。
注意多组输入输出!!!!!!

数据范围:
输入描述:
输入一个整数

输出描述:
计算整数二进制中1的个数

示例1
输入:
5

输出:
2

说明:
5的二进制表示是101,有2个1
示例2
输入:
0

输出:
0
代码

#include<stdio.h>
#include<math.h>

int count(int in)
{
    int num=0;
    
    while(in>0)
    {
        num+=in&1;
        in = in>>1;
    }
    
    return num;
}

int main()
{
    int in;
    
    while(scanf("%d", &in) != EOF)
    {
            printf("%d\n", count(in));
    }
}

65 DNA序列

描述
一个 DNA 序列由 A/C/G/T 四个字母的排列组合组成。 G 和 C 的比例(定义为 GC-Ratio )是序列中 G 和 C 两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的 GC-Ratio 可能是基因的起始点。

给定一个很长的 DNA 序列,以及限定的子串长度 N ,请帮助研究人员在给出的 DNA 序列中从左往右找出 GC-Ratio 最高且长度为 N 的第一个子串。
DNA序列为 ACGT 的子串有: ACG , CG , CGT 等等,但是没有 AGT , CT 等等

数据范围:字符串长度满足 ,输入的字符串只包含 A/C/G/T 字母
输入描述:
输入一个string型基因序列,和int型子串的长度

输出描述:
找出GC比例最高的子串,如果有多个则输出第一个的子串

示例1
输入:
ACGT
2

输出:
CG

说明:
ACGT长度为2的子串有AC,CG,GT3个,其中AC和GT2个的GC-Ratio都为0.5,CG为1,故输出CG
示例2
输入:
AACTGTGCACGACCTGA
5

输出:
GCACG

说明:
虽然CGACC的GC-Ratio也是最高,但它是从左往右找到的GC-Ratio最高的第2个子串,所以只能输出GCACG。
代码

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char *str = (char *)malloc(sizeof(char )*500);
    while(gets(str))
    {
        int n;
        scanf("%d", &n);
        char *pstr = str;
        int count, max=0;
        for(int i=0; i<strlen(str); i++)
        {
            count=0;
            for(int j=i; j<(i+n); j++)
            {
                if(str[j] == 'G' || str[j] == 'C')
                {
                    count++;
                    if(count > max)
                    {
                        max=count;
                        pstr = str+i;
                    }
                }
            }
        }
        for(int i=0; i<n; i++)
        {
            printf("%c", *(pstr+i));
        }
        printf("\n");
    }
    free(str);
    return 0;
}

66 MP3光标位置

描述
MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。
现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:

歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。

光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。

其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。

  1. 歌曲总数大于4的时候(以一共有10首歌为例):

特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。

一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。

其他情况,不用翻页,只是挪动光标就行。
数据范围:本题含有多组输入数据,数据组数 ,命令长度 ,歌曲数量
进阶:时间复杂度: ,空间复杂度:
输入描述:
输入说明:
1 输入歌曲数量
2 输入命令 U或者D

本题含有多组输入数据!
输出描述:
输出说明
1 输出当前列表
2 输出当前选中歌曲
示例1
输入:
10
UUUU

输出:
7 8 9 10
7

代码

#include "stdio.h"

void show(char ch, int *screen, int *top, int *bottom, int *index, int n);

int main(){
    int n;
    while(scanf("%d", &n) != EOF){
      	//***根据歌曲数量初始化屏幕显示内容***//
        int m = n >= 4 ? 4 : n;
        int screen[m];
        for(int i = 0; i < m; i++)
            screen[i] = i + 1;
      	//***初始化第一行显示的歌曲、最后显示的歌曲和光标所在位置的歌曲***//
        int top = screen[0], bottom = screen[m-1], index = screen[0];
      	//***获取命令***//
        char cmd[100];
        scanf("%s", cmd);
      	//***根据命令更新屏幕显示的内容、第一行显示的歌曲、最后显示的歌曲和光标所在位置的歌曲***//
        int len = strlen(cmd);
        for(int i = 0; i < len; i++)
            show(cmd[i], screen, &top, &bottom, &index, n);
      	//***输出屏幕最终显示的内容***//
        for(int i = 0; i < m; i++)
            printf("%d ", screen[i]);
      	//***输出光标所在位置的歌曲***//
        printf("\n%d\n", index);
    }
    return 0;
}

void show(char ch, int *screen, int *top, int *bottom, int *index, int n){
  	//***情况1:命令为向上,且歌曲数量>4***//
    if(ch == 'U' && n > 4){
      	//***若光标在第一行,且第一行为第一首歌,则翻页:最后一行为最后一首歌,第一行为倒数第四首歌,光标在最后一行,同时更新屏幕显示的内容***//
        if(*index == 1){
            *bottom = n;
            *top = n - 3;
            *index = n;
            int temp = *bottom;
            for(int i = 3; i >= 0; i--)
                screen[i] = temp--;
        }
      	//***若光标在第一行,且第一行不为第一首歌,则整个歌曲列表向下移***//
        else if(*index == *top){
            (*top)--;
            (*index)--;
            (*bottom)--;
            int temp = *top;
            for(int i = 0; i <= 3; i++)
                screen[i] = temp++;
        }
      	//***若光标不在第一行,则只需将光标往上移***//
        else
            (*index)--;
    }
  	//***情况2:命令为向下,且歌曲数量>4***//
    else if(ch == 'D' && n > 4){
      	//***若光标在最后一行,且最后一行为最后一首歌,则翻页:第一行为第一首歌,最后一行为第四首歌,光标在第一行,同时更新屏幕显示的内容***//
        if(*index == n){
            *top = 1;
            *bottom = 4;
            *index = 1;
            int temp = *top;
            for(int i = 0; i <= 3; i++)
                screen[i] = temp++;
        }
      	//***若光标在最后一行,且最后一行不为最后一首歌,则整个歌曲列表向上移***//
        else if(*index == *bottom){
            (*top)++;
            (*index)++;
            (*bottom)++;
            int temp = *top;
            for(int i = 0; i <= 3; i++)
                screen[i] = temp++;
        }
      	//***若光标不在最后一行,则只需将光标往下移***//
        else
            (*index)++;
    }
  	//***情况3:命令为向上,且歌曲数量<=4***//
    else if(ch == 'U' && n <= 4){
      	//***若光标在第一行,则光标移至最后一行***//
        if(*index == 1)
            *index = n;
      	//***若光标不在第一行,则光标往上移***//
        else
            (*index)--;
    }
  	//***情况4:命令为向下,且歌曲数量<=4***//
    else if(ch == 'D' && n <= 4){
      	//***若光标在最后一行,则光标移至第一行***//
        if(*index == n)
            *index = 1;
      	//***若光标不在最后一行,则光标往下移***//
        else
            (*index)++;
    }
}

67 查找两个字符串a,b中的最长公共子串

描述
查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!

本题含有多组输入数据!
数据范围:字符串长度,
进阶:时间复杂度:,空间复杂度:
输入描述:
输入两个字符串

输出描述:
返回重复出现的字符
示例1
输入:
abcdefghijklmnop
abcsafjklmnopqrstuvw

输出:
jklmnop
代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX 1500

int main()
{
    int dp[MAX][MAX] = {0};
    char str1[MAX] = {'\0'}, str2[MAX] = {'\0'};
    while(gets(str1))
    {
        gets(str2);
        int len1=strlen(str1);
int len2=strlen(str2);
        //str1保存短字符串
        if(len1 > len2)
        {
            char temp[MAX] = {'\0'};
            strcpy(temp, str1);
            strcpy(str1, str2);
            strcpy(str2, temp);
            len1 += len2;
            len2 = len1 - len2;
            len1 = len1 - len2;
        }
        //maxlen记录最长公共字串长度,index记录第一个最长字串的最后一个字符位置
        int maxlen=0, index;
        for(int i=0; i<len1; i++)
        {
            for(int j=0; j<len2; j++)
            {
                if(str1[i] == str2[j])
                {
                    dp[i+1][j+1] = dp[i][j] + 1;
                    if(maxlen < dp[i+1][j+1])
                    {
                        maxlen = dp[i+1][j+1];
                        index = i;
                    }
                }
                else
                {
                    dp[i+1][j+1] = 0;
                }
            }
        }
        char out[MAX] = {'\0'};
        strncpy(out, &str1[index-maxlen+1], maxlen);
        printf("%s\n", out);
    }
    return 0;
}

68 配置文件恢复

描述
有6条配置命令,它们执行的结果分别是:

命 令 执 行
reset reset what
reset board board fault
board add where to add
board delete no board at all
reboot backplane impossible
backplane abort install first
he he unknown command
注意:he he不是命令。

为了简化输入,方便用户,以“最短唯一匹配原则”匹配:
1、若只输入一字串,则只匹配一个关键字的命令行。例如输入:r,根据该规则,匹配命令reset,执行结果为:reset what;输入:res,根据该规则,匹配命令reset,执行结果为:reset what;
2、若只输入一字串,但匹配命令有两个关键字,则匹配失败。例如输入:reb,可以找到命令reboot backpalne,但是该命令有两个关键词,所有匹配失败,执行结果为:unknown command
3、若输入两字串,则先匹配第一关键字,如果有匹配,继续匹配第二关键字,如果仍不唯一,匹配失败。
例如输入:r b,找到匹配命令reset board 和 reboot backplane,执行结果为:unknown command。
例如输入:b a,无法确定是命令board add还是backplane abort,匹配失败。
4、若输入两字串,则先匹配第一关键字,如果有匹配,继续匹配第二关键字,如果唯一,匹配成功。例如输入:bo a,确定是命令board add,匹配成功。
5、若输入两字串,第一关键字匹配成功,则匹配第二关键字,若无匹配,失败。例如输入:b addr,无法匹配到相应的命令,所以执行结果为:unknow command。
6、若匹配失败,打印“unknown command”

注意:有多组输入。
数据范围:数据组数:,字符串长度
进阶:时间复杂度:,空间复杂度:
输入描述:
多行字符串,每行字符串一条命令

输出描述:
执行结果,每条命令输出一行

示例1
输入:
reset
reset board
board add
board delet
reboot backplane
backplane abort

输出:
reset what
board fault
where to add
no board at all
impossible
install first

代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char *cmd1[6] = {"reset", "reset", "board", "board", "reboot", "backplane"};
char *cmd2[6]= {"no use", "board", "add", "delete", "backplane", "abort"};

void cmd_out(int index)
{
    switch(index)
    {
        case 0:
            printf("reset what\n");
            break;
        case 1:
            printf("board fault\n");
            break;
        case 2:
            printf("where to add\n");
            break;
        case 3:
            printf("no board at all\n");
            break;
        case 4:
            printf("impossible\n");
            break;
        case 5:
            printf("install first\n");
            break;
        default:
            printf("unknown command\n");
            break;
    }
}

int main()
{
    char in[28] = {'\0'};
    while(gets(in))
    {
        int len = strlen(in);
        if(len > 16)
        {
            printf("unknown command\n");
            continue;
        }
        int blank_flag = 1, pos;        //blank_flag判断是否有空格,pos空格的位置
        for(int i=0; i<len; i++)
        {
            if(in[i] == ' ')
            {
                blank_flag = 0;
                pos = i;
                break;
            }
        }
        //输入一个字串的情况
        if(blank_flag)
        {

            if(strncmp(in, cmd1[0], len) == 0)
                printf("reset what\n");
            else
                printf("unknown command\n");
        }
        //输入两个字串的情况
        else
        {
            int cnt=0, index;
            for(int i=1; i<6; i++)
            {
                if(strncmp(in, cmd1[i], pos) == 0 &&
                   strncmp(in+pos+1, cmd2[i], len-pos-1) == 0)
                {
                    cnt++;
                    index=i;
                }
            }
            if(cnt==1)
                cmd_out(index);
            else
                printf("unknown command\n");
        }
    }
    return 0;
}

69 24点游戏算法

描述
给出4个1-10的数字,通过加减乘除运算,得到数字为24就算胜利,除法指实数除法运算,本题对数字选取顺序无要求,但每个数字仅允许使用一次,且不考虑括号运算
此题允许数字重复,如3 3 4 4为合法输入,此输入一共有两个3,但是每个数字只允许使用一次,则运算过程中两个3都被选取并进行对应的计算操作。
输入描述:
本题有多组案例。对于每组案例读入4个[1,10]的整数,数字允许重复,测试用例保证无异常数字。

输出描述:
对于每组案例,输出一行表示能否得到24点,能输出true,不能输出false

示例1
输入:
7 2 1 10

输出:
true
代码

#include <stdio.h>
#include <math.h>
int dfs(float *num,int len){
    float newnum[len-1],n;
    int i,j,k,z;
    if(len==1){
        n=num[0]-24;
        if(n<0) n*=-1;
        if(n<0.0001) {
            return 1;}
        else return 0;
    }
    for(i=0;i<len;i++){
        for(j=0;j<len;j++){
            if(i!=j){
                for(k=0;k<len;k++){
                    if((k!=i)&&(k!=j)) newnum[1]=num[k];
                    for(z=0;z<len;z++){
                        if((z!=i)&&(z!=j)&&(z!=k)) newnum[2]=num[z];
                    }
                }
                newnum[0]=num[i]+num[j];
                if(dfs(newnum,len-1)) return 1;
                
                newnum[0]=num[i]-num[j];
                if(dfs(newnum,len-1)) return 1;
                
                newnum[0]=num[i]*num[j];
                if(dfs(newnum,len-1)) return 1;
                
                if(num[j]!=0){
                    newnum[0]=num[i]/num[j];
                    if(dfs(newnum,len-1)) return 1;
                }
            }
        }
    }
    return 0;
}

int main(void) { 
	float nums[4];
	while(scanf("%f",nums)!=-1){
	    scanf("%f",nums+1);
	    scanf("%f",nums+2);
	    scanf("%f",nums+3);
	    if(dfs(nums,4))
	    printf("true\n");
        else printf("false\n");
	}
	return 0;
}

70 成绩排序

描述
查找和排序

题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩
都按先录入排列在前的规则处理。

例示:
jack 70
peter 96
Tom 70
smith 67

从高到低 成绩
peter 96
jack 70
Tom 70
smith 67

从低到高

smith 67

jack 70

Tom 70
peter 96

注:0代表从高到低,1代表从低到高

注意:本题含有多组输入数据!
数据范围:人数:,数据组数:
进阶:时间复杂度:,空间复杂度:
输入描述:
输入多行,先输入要排序的人的个数,然后分别输入他们的名字和成绩,以一个空格隔开

输出描述:
按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开

示例1
输入:
3
0
fang 90
yang 50
ning 70
输出:
fang 90
ning 70
yang 50

示例2
输入:
3
1
fang 90
yang 50
ning 70
3
0
moolgouua 43
aebjag 87
b 67

输出:
yang 50
ning 70
fang 90
aebjag 87
b 67
moolgouua 43

说明:
第一组用例:
3
1
fang 90
yang 50
ning 70
升序排序为:
yang 50
ning 70
fang 90
第二组降序为:
aebjag 87
b 67
moolgouua 43
代码

#include<stdio.h>
#include<string.h>

typedef struct Node{
    char name[100];
    int grade;
}Node;

int main()
{
    int n,sj;
   
    while(EOF != scanf("%d%d",&n,&sj))
    {
        int i,j,k;
        Node narr[200];
        Node temp;
       for(i=0; i<n;i++)
       {
           scanf("%s%d",narr[i].name,&narr[i].grade);
       }
        
        if(sj==0) //降序
        {
            for(i=0;i<n-1;i++)
            {
                for(j=0;j<n-1-i;j++)
                {
                    if(narr[j].grade < narr[j+1].grade)
                    {
                        temp.grade = narr[j].grade;    
strcpy(temp.name, narr[j].name);
                        narr[j].grade = narr[j+1].grade;  
strcpy(narr[j].name, narr[j+1].name);
                        narr[j+1].grade = temp.grade; strcpy(narr[j+1].name, temp.name);
                    }
                }
            }
        }else if(sj == 1)
        {
            for(i=0;i<n-1;i++)
            {
                for(j=0;j<n-1-i;j++)
                {
                    if(narr[j].grade > narr[j+1].grade)
                    {
                        temp.grade = narr[j].grade;    strcpy(temp.name, narr[j].name);
                        narr[j].grade = narr[j+1].grade;  strcpy(narr[j].name, narr[j+1].name);
                        narr[j+1].grade = temp.grade; strcpy(narr[j+1].name, temp.name);
                    }
                }
            }
        }
        
        for(i=0;i<n;i++)
        {
            printf("%s %d\n",narr[i].name,narr[i].grade);
        }
        
    }
    
    return 0;
}

72 矩阵乘法

描述
如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。这个矩阵的每个元素是由下面的公式决定的

矩阵的大小不超过100*100
输入描述:
输入包含多组数据,每组数据包含:
第一行包含一个正整数x,代表第一个矩阵的行数
第二行包含一个正整数y,代表第一个矩阵的列数和第二个矩阵的行数
第三行包含一个正整数z,代表第二个矩阵的列数
之后x行,每行y个整数,代表第一个矩阵的值
之后y行,每行z个整数,代表第二个矩阵的值

输出描述:
对于每组输入数据,输出x行,每行z个整数,代表两个矩阵相乘的结果
示例1
输入:
2
3
2
1 2 3
3 2 1
1 2
2 1
3 3

输出:
14 13
10 11

说明:
1 2 3
3 2 1
乘以
1 2
2 1
3 3
等于
14 13
10 11
示例2
输入:
2
2
2
1 1
1 1
1 1
1 1
16
8
7
17 19 16 19 14 1 14 9
7 2 7 9 16 14 16 12
13 3 3 17 5 9 8 16
1 14 16 10 13 13 14 1
13 13 15 4 7 2 6 16
16 15 5 5 15 13 1 11
11 5 0 16 14 7 7 15
0 16 4 7 16 6 0 15
2 14 11 2 17 17 5 12
8 13 11 10 1 17 10 8
15 16 17 15 7 8 13 14
5 19 11 3 11 14 5 4
9 16 13 11 15 18 0 3
15 3 19 9 5 14 12 3
9 8 7 11 18 19 14 18
12 19 9 1 0 18 17 10
5 18 16 19 6 12 5
1 17 1 5 9 16 3
14 16 4 0 19 3 6
11 9 15 18 11 17 13
5 5 19 3 16 1 12
12 13 19 1 10 5 18
19 18 6 18 19 12 3
15 11 6 5 10 17 19
输出:
2 2
2 2
1020 1490 1063 1100 1376 1219 884
966 1035 1015 715 1112 772 920
822 948 888 816 831 920 863
855 1099 828 578 1160 717 724
745 1076 644 595 930 838 688
635 1051 970 600 880 811 846
748 879 952 772 864 872 878
526 722 645 335 763 688 748
764 996 868 362 1026 681 897
836 1125 785 637 940 849 775
1082 1476 996 968 1301 1183 953
609 987 717 401 894 657 662
700 1083 1022 527 1016 746 875
909 1162 905 722 1055 708 720
1126 1296 1240 824 1304 1031 1196
905 1342 766 715 1028 956 749
代码

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
    int arow,arol,brow,bcol;
    while(scanf("%d",&arow)!=EOF)
    {
        scanf("%d",&arol);
        scanf("%d",&bcol);
        brow = arol;
        int a[arow][arol];
        int b[brow][bcol];
        int out[arow][bcol];
        int tmp=0;
        for(int i =0;i<arow;i++)
        {
            for(int j =0;j<arol;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        for(int i =0;i<brow;i++)
        {
            for(int j =0;j<bcol;j++)
            {
                scanf("%d",&b[i][j]);
            }
        }
        for(int i =0;i<arow;i++)
        {
            for(int j =0;j<bcol;j++)
            {
                for(int m =0;m<arol;m++)
                {
                    tmp += a[i][m]*b[m][j];
                }
                out[i][j] =tmp;
                tmp =0;
            }
        }
         for(int i =0;i<arow;i++)
        {
            for(int j =0;j<bcol;j++)
            {
                printf("%d ",out[i][j]);
            }
             printf("\n");
        }
    }
    return 0;
}

73 矩阵乘法计算量估算

描述
矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:

A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

计算ABC有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

编写程序计算不同的计算顺序需要进行的乘法次数。

本题含有多组样例输入!
数据范围:数据组数:,矩阵个数:,行列数:
进阶:时间复杂度:,空间复杂度:

输入描述:
输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
计算的法则为一个字符串,仅由左右括号和大写字母(‘A’~‘Z’)组成,保证括号是匹配的且输入合法!

输出描述:
输出需要进行的乘法次数

示例1
输入:
3
50 10
10 20
20 5
(A(BC))

输出:
3500
代码

#include<stdio.h>
#include<string.h>
#include<ctype.h>

typedef struct Node{
    int rowNum;
    int colNum;
}Matrix;

int main()
{
    int n;
    while(EOF != scanf("%d",&n))
    {
        Matrix matrix[n];
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&matrix[i].rowNum,&matrix[i].colNum);
        }
        char str[100];
        scanf("%s",str);
        Matrix stack[n];
        int index = -1;
        
        int alphaidnex = -1;
        int len = strlen(str);
        
        int countSum = 0;
        
        for(int i=0;i<len;i++)
        {
            if(isupper(str[i]))
            {
                ++alphaidnex;
                ++index;
                stack[index].rowNum = matrix[alphaidnex].rowNum;  // 入栈
                stack[index].colNum = matrix[alphaidnex].colNum;
            }else if(str[i] == ')')
            {
                Matrix temp;  
                temp.rowNum = stack[index-1].rowNum;
                temp.colNum = stack[index].colNum;
                countSum += stack[index-1].rowNum*stack[index].colNum*stack[index-1].colNum;
                index -= 2;   //出栈计算
                ++index; // 入栈计算结果
                stack[index].rowNum = temp.rowNum;
                stack[index].colNum = temp.colNum;
            }
        }
        printf("%d\n",countSum);
    }
    
    return 0;
}

74 字符串通配符

描述
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
:匹配0个或以上的字符(注:能被和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符

注意:匹配时不区分大小写。

输入:
通配符表达式;
一组字符串。
输出:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
注意:本题含有多组样例输入!
数据范围:数据组数:,字符串长度:
进阶:时间复杂度:,空间复杂度:
输入描述:
先输入一个带有通配符的字符串,再输入一个需要匹配的字符串

输出描述:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

示例1
输入:
te?t*.*
txt12.xls

输出:
false

示例2
输入:
z
zz

输出:
false

示例3
输入:
pq
pppq

输出:
false

示例4
输入:
**Z
0QZz

输出:
true

示例5
输入:
?Bc?
abcd

输出:
true

示例6
输入:
h*?*a
h#a

输出:
false

说明:
根据题目描述可知能被和?匹配的字符仅由英文字母和数字0到9组成,所以?不能匹配#,故输出false
示例7
输入:
p
pqp**pqpp*ppq
pppppppqppqqppqppppqqqppqppqpqqqppqpqpppqpppqpqqqpqqp

输出:
false
代码

#include <stdio.h>

int match(char *str1,char*str2){
    if((str1[0]=='\0')&&(str2[0]=='\0')) return 1;
    else if ((str1[0]=='\0')||(str2[0]=='\0')) return 0;
    
    if((str1[0]=='?')||(str1[0]==str2[0])) return match(str1+1, str2+1);
    if(str1[0]=='*') {
        if(*(str1+1)=='*')
        return (match(str1+1+1, str2)||match(str1+1+1, str2+1)||match(str1+1, str2+1));
        else return (match(str1+1, str2)||match(str1+1, str2+1)||match(str1, str2+1));
    }
        
    return 0;
}

int main(){
    char str1[1000],str2[1000];
    int loc,len1,len2,i,j;
    while(scanf("%s",str1)!=-1){
        scanf("%s",str2);
        len1=strlen(str1);
        len2=strlen(str2);
        int flag=1;
        for(i=0;i<len1;i++){
            if((str1[i]>='A')&&(str1[i]<='Z'))
                str1[i]+=32;
        }
        for(i=0;i<len2;i++){
            if((str2[i]>='A')&&(str2[i]<='Z'))
                str2[i]+=32;
      
            if(((str2[i]<'a')||(str2[i]>'z'))&&(str2[i]!='.')&&((str2[i]<'0')||(str2[i]>'9'))){
                flag=0;
            }
        }
        

        if((flag)&&(match(str1,str2))) printf("true\n");
        else printf("false\n");
    }
    
    return 0;
}

75 百钱买百鸡问题

描述
公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
现要求你打印出所有花一百元买一百只鸡的方式。
输入描述:
输入任何一个整数,即可运行程序。
输出描述:
输出有数行,每行三个整数,分别代表鸡翁,母鸡,鸡雏的数量

示例1
输入:
1

输出:
0 25 75
4 18 78
8 11 81
12 4 84

代码

#include <stdio.h>

int main()
{
    int n;
    while(scanf("%d", &n)!=EOF)
    {
        for(int i=0; i<=20; i++)
        {
            for(int j=0; j<=33; j++)
            {
                for(int k=0; k<=100; k++)
                {
                    if((3*k + j + i)==100 && (k+3*j + 5*i)==100)
                    {
                        printf("%d %d %d\n", i, j, k*3);
                    }
                }
            }
        }
    }
    return 0;
}

76 计算日期到天数转换

描述
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。
进阶:时间复杂度:,空间复杂度:
输入描述:
输入一行,每行空格分割,分别是年,月,日

输出描述:
输出是这一年的第几天
示例1
输入:
2012 12 31

输出:
366

示例2
输入:
1982 3 4

输出:
63
代码

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int month_days[12]  = {31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
    int year, month, day;
    while(scanf("%d %d %d\n", &year, &month, &day) != EOF)
    {
        int days = 0;
        if(month >= 2)
            days = month_days[month - 2] + day;
        else
            days = day;
        if((year%4 == 0 && year%100 != 0) || year %400 == 0)
            days ++;
        printf("%d\n", days);
    }
    return 0;
}

77 参数解析

描述
在命令行输入如下命令:

xcopy /s c:\ d:\e,

各个参数如下:

参数1:命令字xcopy

参数2:字符串/s

参数3:字符串c:\

参数4: 字符串d:\e

请编写一个参数解析程序,实现将命令行各个参数解析出来。
解析规则:

1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:\program files” "d:“时,参数仍然是4个,第3个参数应该是字符串C:\program files,而不是C:\program,注意输出参数时,需要将”"去掉,引号不存在嵌套情况。
3.参数不定长

4.输入由用例保证,不会出现不符合要求的输入
数据范围:字符串长度:
进阶:时间复杂度:,空间复杂度:
输入描述:
输入一行字符串,可以有空格

输出描述:
输出参数个数,分解后的参数,每个参数都独占一行

示例1
输入:
xcopy /s c:\ d:\e

输出:
4
xcopy
/s
c:\
d:\e

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char a[1000];
    while(gets(a)!=NULL)
    {
        int len = strlen(a);
        int flag = 0;
        int count = 0;
        for(int i =0;i<len;i++)
        {
            if(a[i]=='"'&&flag==0)
            {
                flag = 1;
            }
            else if(a[i]=='"'&&flag==1)
            {
                flag = 0;
            }
            else if(a[i]==' '&&flag==0)
            {
                count++;
            }
        }
        printf("%d\n",count+1);
        for(int i =0;i<len;i++)
        {
            if(a[i]==' '&&flag==0)
            {
                printf("\n");
                continue;
            }
            if(a[i]=='"'&&flag==0)
            {
                flag = 1;
                continue;
            }
            if(a[i]=='\"'&&flag==1)
            {
                flag = 0;
                continue;
            }
             printf("%c",a[i]);
        }
        printf("\n");
    }

    return 0;
}

78 公共子串计算

描述
给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。
数据范围:字符串长度:
进阶:时间复杂度: ,空间复杂度:
输入描述:
输入两个只包含小写字母的字符串
输出描述:
输出一个整数,代表最大公共子串的长度

示例1
输入:
asdfas
werasdfaswer

输出:
6
代码

#include <stdio.h>
#include <string.h>
int main(void)
{
    char str1[100];
    char str2[100];

    while((scanf("%s %s",&str1,&str2))!=EOF)
    {
        int max =0;
        for(int i=0;i<strlen(str1);i++)
        {
            for(int j=0;j<strlen(str2);j++)
            {
                int m =0;
                int n =0;
                while(str1[m+i]!='\0' && str2[n+j]!='\0' &&
toupper(str1[m+i])==toupper(str2[n+j]))
                {
                    n++;
                    m++;
                    if(n > max)
                        max =n;
                }
            }
        }
        printf("%d\n",max);
    }
    return 0;
}

79 尼科彻斯定理(题没看懂)

描述
验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
例如:
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。
本题含有多组输入数据。
数据范围:数据组数:,
进阶:时间复杂度:,空间复杂度:

输入描述:
输入一个int整数

输出描述:
输出分解后的string

示例1
输入:
6

输出:
31+33+35+37+39+41

代码

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int num;
    while(scanf("%d", &num) != EOF)
    {
        int tri = num * num * num;
        for(int i=1; i<65000; i += 2)
        {
            int sum = (i+(i+(num-1)*2))*num/2;
            if(sum == tri)
            {
                for(int j=0; j<num-1; j++)
                {
                    printf("%d+", i+2*j);
                }
                printf("%d\n", i+2*(num-1));
            }
        }
    }
    return 0;
}

80 火车进站

描述
给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。
要求输出所有火车出站的方案,以字典序排序输出。
数据范围:
进阶:时间复杂度:,空间复杂度:
输入描述:
有多组测试用例,每一组第一行输入一个正整数N(0

输出描述:
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。

示例1
输入:
3
1 2 3

输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1

说明:
第一种方案:1进、1出、2进、2出、3进、3出
第二种方案:1进、1出、2进、3进、3出、2出
第三种方案:1进、2进、2出、1出、3进、3出
第四种方案:1进、2进、2出、3进、3出、1出
第五种方案:1进、2进、3进、3出、2出、1出
请注意,[3,1,2]这个序列是不可能实现的。
代码

#include <stdio.h>
#include <string.h>
struct stack{
    char num[10];
    int top;
};

void add(char n,struct stack *sta){
    sta->num[++(sta->top)]=n;
}

char pop(struct stack *sta){
    char te;
    te=sta->num[sta->top];
    sta->top--;
    return te;
}

struct stack train1,train2;
int m=0;
char strain[20];
char strai[10000][20];
void dfs(int n){
    char tin,tout;
    if((train1.top==-1)&&(train2.top==-1)) {
        
        memcpy(strai[m], strain,n);
        m++;
        return;
    }
    if((train1.top!=-1)){
        if(train2.top==-1) {
            tin=pop(&train1);
            add(tin,&train2);
            dfs(n);
            add(tin,&train1);
            pop(&train2);
        }
        else{
            tout=pop(&train2);
            strain[n]=tout;
            dfs(n+1);
            add(tout,&train2);
            tin=pop(&train1);
            add(tin,&train2);
            dfs(n);
            pop(&train2);
            add(tin,&train1);
        }
    }
    else {
        tout=pop(&train2);
        strain[n]=tout;
        dfs(n+1); 
        add(tout,&train2);
    }
    return;
}

int main(){
    int i,j,n;
    char str[10],temp[10];
    
    while(scanf("%d",&n)!=-1){
        train1.top=-1;
        train2.top=-1;
        m=0;
        for(i=0;i<n;i++){
            scanf("%s",str+i);
            add(str[i],&train2);
        }
        for(i=0;i<n;i++) add(pop(&train2),&train1);
       memset(strai, '\0', 20000);
        dfs(0);

        for(i=0;i<m-1;i++){
            for(j=0;j<m-1-i;j++){
                if(strcmp(strai[j],strai[j+1])>0){
                    memcpy(temp, strai[j],n);
                    memcpy(strai[j], strai[j+1],n);
                    memcpy(strai[j+1], temp,n);
                }
            }
        }
        for(i=0;i<m;i++){
            for(j=0;j<n;j++) printf("%c ",strai[i][j]);
            printf("\n");
        }
    }
    return 0;
}

81 整型数组合并

描述
题目标题:

将两个整型数组按照升序合并,并且过滤掉重复数组元素。
输出时相邻两数之间没有空格。
请注意本题有多组样例。

输入描述:
输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值

输出描述:
输出合并之后的数组

示例1
输入:
3
1 2 5
4
-1 0 3 2

输出:
-101235

代码

#include <stdio.h>

int cmp (int *a, int *b)
{
    return (*a - *b);
}
int main()
{
    int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
    int a1[1024] = {0};
    int a2[1024] = {0};

    scanf("%d", &n1);
    for (int i = 0; i < n1; i++) {
        scanf("%d", &a1[i]);
    }

    scanf("%d", &n2);
    for (int i = n1; i < n1 + n2; i++) {
        scanf("%d", &a1[i]);
    }
    scanf("%d", &n3);
    for (int i = 0; i < n3; i++) {
        scanf("%d", &a2[i]);
    }
    scanf("%d", &n4);
    for (int i = n3; i < n3 + n4; i++) {
        scanf("%d", &a2[i]);
    }

    qsort(a1, n1+n2, sizeof(int), cmp);
    qsort(a2, n3+n4, sizeof(int), cmp);
    for(int i = 0; i < n1+n2; i++) {
        if (a1[i] != a1[i-1]) {
            printf("%d", a1[i]);
        }
    }
    printf("\n");
    for(int i = 0; i < n3+n4; i++) {
        if (a2[i] != a2[i-1]) {
            printf("%d", a2[i]);
        }
    }
    return 0;
}

82 字符串字符匹配

描述
判断短字符串S中的所有字符是否在长字符串T中全部出现。
请注意本题有多组样例输入。
数据范围:
进阶:时间复杂度:,空间复杂度:
输入描述:
输入两个字符串。第一个为短字符串,第二个为长字符串。两个字符串均由小写字母组成。

输出描述:
如果短字符串的所有字符均在长字符串中出现过,则输出字符串"true"。否则输出字符串"false"。

示例1
输入:
bc
abc
apgmlivuembu
tyjmrcuneguxmsqwjslqvfmw
bca
abc

输出:
true
false
true

说明:
第一组样例:
bc
abc
其中abc含有bc,输出"true"
第二组样例,上面短字符串的a就没有在下面长字符串出现,输出"false"

代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int IsAllCharExist(char* pShortString,char* pLongString)
{
    int len_short = strlen(pShortString);
    int len_long = strlen(pLongString);
    int hash_table[128] = {0};
    int count = 0;
    for(int i=0; i<len_long; i++)
    {
        hash_table[pLongString[i]]=1;
    }
    for(int i=0; i<len_short; i++)
    {
        if(hash_table[pShortString[i]])
            count++;
    }
    if(count == len_short)
        return 1;
    else
        return 0;
}

int main()
{
    char str_short[50]={'\0'}, str_long[200]={'\0'};
    while(gets(str_short))
    {
        gets(str_long);
        int flag = IsAllCharExist(str_short, str_long);
        if(flag)
            printf("true\n");
        else
            printf("false\n");
    }
    return 0;
}

83 将真分数分解为埃及分数

描述
分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。
注:真分数指分子小于分母的分数,分子和分母有可能gcd不为1!
如有多个解,请输出任意一个。
请注意本题含有多组样例输入!
输入描述:
输入一个真分数,String型
输出描述:
输出分解后的string
示例1
输入:
8/11
2/4

输出:
1/2+1/5+1/55+1/110
1/3+1/6

说明:
第二个样例直接输出1/2也是可以的
思想

古埃及人所指的分数,其分子必等于1,例如:1/2、1/3、1/4。
数学家斐波那契提出的一种求解埃及分数的算法:
设某个真分数的分子为a,分母为b;
把c=(b/a+1)作为分解式中第一个埃及分数的分母;
将a-b%a作为新的a;
将b*c作为新的b;
如果a等于1,则最后一个埃及分数为1/b,算法结束;
如果a大于1但是a能整除b,则最后一个埃及分数为1/(b/a),算法结束;
否则重复上面的步骤。

代码

#include<stdio.h>

int main(){
    int a,b,c,i=0;
    char buffer[20]={0};
    while(scanf("%d/%d",&a,&b)!=EOF)
    {
        while(1){
            c=(b/a+1);
            a=a-b%a;
            b=b*c;
            i+=sprintf(buffer+i,"1/%d+",c);
            if(a==1)
            {
                i+=sprintf(buffer+i,"1/%d",b);
                break;
            }

            if(a>1&&b%a==0)
            {
                i+=sprintf(buffer+i,"1/%d",b/a);
                break;
            }
        }

        printf("%s\n",buffer);
        i=0;
        memset(buffer,0,20);
    }
}

84 二维数组操作

描述
有一个 大小的数据表,你会依次进行以下5种操作:
1.输入 和 ,初始化 大小的表格。
2.输入x_1x1、y_1y1、x_2x2、y_2y2,交换坐标在(x_1,y_1)(x1,y1)和(x_2,y_2)(x2,y2)的两个数。
3.输入 ,在第 行上方添加一行。
4.输入 ,在第 列左边添加一列。
5.输入 、 ,查找坐标为 的单元格的值。
请编写程序,判断对表格的各种操作是否合法。
详细要求:
1.数据表的最大规格为9行*9列,对表格进行操作时遇到超出规格应该返回错误。
2.对于插入操作,如果插入后行数或列数超过9了则应返回错误。如果插入成功了则将数据表恢复至初始化的 大小,多出的数据则应舍弃。
3.所有输入坐标操作,对 大小的表格,行号坐标只允许0m-1,列号坐标只允许0n-1。超出范围应该返回错误。
本题含有多组样例输入!
数据范围:数据组数:
进阶:时间复杂度: ,空间复杂度:
输入描述:
输入数据按下列顺序输入:
1 表格的行列值
2 要交换的两个单元格的行列值
3 输入要插入的行的数值
4 输入要插入的列的数值
5 输入要查询的单元格的坐标
输出描述:
输出按下列顺序输出:
1 初始化表格是否成功,若成功则返回0, 否则返回-1
2 输出交换单元格是否成功
3 输出插入行是否成功
4 输出插入列是否成功
5 输出查询单元格数据是否成功
示例1
输入:
4 9
5 1 2 6
0
8
2 3
4 7
4 2 3 2
3
3
4 7

输出:
0
-1
0
-1
0
0
-1
0
0
-1

说明:
本组样例共有2组样例输入。
第一组样例:
1.初始化数据表为4行9列,成功
2.交换第5行1列和第2行6列的数据,失败。因为行的范围应该是(0,3),不存在第5行。
3.在第0行上方添加一行,成功。
4.在第8列左边添加一列,失败。因为列的总数已经达到了9的上限。
5.查询第2行第3列的值,成功。
第二组样例:
1.初始化数据表为4行7列,成功
2.交换第4行2列和第3行2列的数据,失败。因为行的范围应该是(0,3),不存在第4行。
3.在第3行上方添加一行,成功。
4.在第3列左边添加一列,成功。
5.查询第4行7列的值,失败。因为虽然添加了一行一列,但数据表会在添加后恢复成4行7列的形态,所以行的区间仍然在[0,3],列的区间仍然在[0,6],无法查询到(4,7)坐标。
代码

#include<stdio.h>
int main()
{
    int m,n;
    int x1,y1,x2,y2,x3,y3;
    int addrow,addcol;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        if(m>9||n>9)
        {
            printf("%d\n",-1);
        }
        else
        {
            printf("%d\n",0);
        }
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        {
            if(x1>=m||x2>=m||y1>=n||y2>=n)
            {
                printf("%d\n",-1);
            }
            else
            {
                printf("%d\n",0);
            }
        }
        scanf("%d",&addrow);
         if(m+1>9||addrow>=m)
        {
            printf("%d\n",-1);
        }
        else
        {
            printf("%d\n",0);
        }
        scanf("%d",&addcol);
         if(n+1>9||addcol>=n)
        {
            printf("%d\n",-1);
        }
        else
        {
            printf("%d\n",0);
        }
        scanf("%d%d",&x3,&y3);
        if(x3>=m||y3>=n)
        {
            printf("%d\n",-1);
        }
        else
        {
            printf("%d\n",0);
        }
    }
    return 0;
}

85 统计大写字母个数

描述
找出给定字符串中大写字符(即’A’-‘Z’)的个数。
数据范围:字符串长度:
字符串中可能包含空格或其他字符
进阶:时间复杂度:,空间复杂度:
输入描述:
本题含有多组样例输入
对于每组样例,输入一行,代表待统计的字符串

输出描述:
对于每组样例,输出一个整数,代表字符串中大写字母的个数

示例1
输入:
add123#KaTeX parse error: Expected 'EOF', got '&' at position 17: …#%#O 150175017(&̲^%&vabovbao
A 1 0 11

输出:
1
0
1
代码

#include<stdio.h>
#include<string.h>
int main()
{
    char str[250];
    while(gets (str))
    {
        int i=0;
        int num=0;
        while(str[i]!='\0')
        {
            if(str[i]>='A'&&str[i]<='Z')
            {
                num++;
            }
            i++;
        }
        printf("%d\n",num);
    }
    return 0;
}

86 最长回文子串

描述
给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串
数据范围:字符串长度
进阶:时间复杂度:,空间复杂度:
输入描述:
输入一个仅包含小写字母的字符串

输出描述:
返回最长回文子串的长度

示例1
输入: +

cdabbacc

输出:
4

说明:
abba为最长的回文子串
思想
选取字符串中一个字符为中心,判断是否左右对称,将对称的最大长度输出
代码

#include<stdio.h>
#include<string.h>

int subpalidromelen(char *chsIn, int i);

int main(int argc, char const *argv[])
{
    char str_in[999];
    char chs[999];
    while ( scanf("%s", str_in) != EOF )
    {
        //将原有字符串间隔加入#,防止偶数字符串的回文数不好计算。奇数+偶数=奇数
        memset(chs, 0X00, sizeof(chs));
        for (int i = 0; i < strlen(str_in); i++)
        {
            strcat(chs, "#");
            sprintf(chs+strlen(chs), "%c", str_in[i]);
        }
        
        strcat(chs, "#");

        int maxHWlen = 0;
        for (int i = 0; i < strlen(chs); i++)
        {
            //中心扩展函数
            if (subpalidromelen(chs, i) > maxHWlen)
            {
                maxHWlen = subpalidromelen(chs, i);
            }
            
        }
        printf("%d\n", maxHWlen);
    }
    
    return 0;
}

int subpalidromelen(char *chsIn, int i)
{
    int len = 0;

    for (int k = 0; k <=i ; k++)
    {
        if (chsIn[i - k] == chsIn[i + k])
        {
            len++;
        }
        else
        {
            break;
        }       
    }
    return len - 1;
}

87 求最大连续bit数

描述
求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1
本题含有多组样例输入。
数据范围:数据组数:,
进阶:时间复杂度:,空间复杂度:
输入描述:
输入一个int类型数字

输出描述:
输出转成二进制之后连续1的个数

示例1
输入:
3
5
200

输出:
2
1
2

说明:
3的二进制表示是11,最多有2个连续的1。
5的二进制表示是101,最多只有1个连续的1
代码

#include <stdio.h>
int main()
{
    int n,a,i,max=0,b,count=0;
    while(1)
    {
        a=scanf("%d",&n);
        if(a==-1)
        {
            break;
        }
        count=0;
        max=0;
        for(i=1;n!=0;i++)
        {
            b=n%2;
            if(b==1)
            {
                count++;
                n=n>>1;
            }
            else
            {
                count=0;
                n=n>>1;
            }
            if(count>max)
            {
                max=count;
            }
        }
        printf("%d\n",max);
    }
    return 0;
 }

88 密码强度等级

描述
密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分。
一、密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符
二、字母:
0 分: 没有字母
10 分: 全都是小(大)写字母
20 分: 大小写混合字母
三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字
四、符号:
0 分: 没有符号
10 分: 1 个符号
25 分: 大于1 个符号
五、奖励:
2 分: 字母和数字
3 分: 字母、数字和符号
5 分: 大小写字母、数字和符号
最后的评分标准:

= 90: 非常安全
= 80: 安全(Secure)
= 70: 非常强
= 60: 强(Strong)
= 50: 一般(Average)
= 25: 弱(Weak)
= 0: 非常弱

对应输出为:
VERY_SECURE

SECURE

VERY_STRONG

STRONG

AVERAGE

WEAK

VERY_WEAK
请根据输入的密码字符串,进行安全评定。
注:
字母:a-z, A-Z
数字:0-9
符号包含如下: (ASCII码表可以在UltraEdit的菜单view->ASCII Table查看)
!"#$%&'()*+,-./ (ASCII码:0x21~0x2F)
:;<=>?@ (ASCII码:0x3A~0x40)
[]^_` (ASCII码:0x5B~0x60)
{|}~ (ASCII码:0x7B~0x7E)

提示:
1 <= 字符串的长度<= 300
输入描述:
本题含有多组输入样例。
每组样例输入一个string的密码
输出描述:
每组样例输出密码等级
示例1
输入:
38$@NoNoNo
123

输出:
VERY_SECURE
WEAK

说明:
第一组样例的密码长度大于等于8个字符,得25分;大小写字母都有所以得20分;有两个数字,所以得20分;包含大于1符号,所以得25分;由于该密码包含大小写字母、数字和符号,所以奖励部分得5分,经统计得该密码的密码强度为25+20+20+25+5=95分。
同理,第二组样例密码强度为5+0+20+0+0=25分。
代码

#include <stdio.h>
#include <string.h>
int main(void)
{
    char str[1000];
    while(scanf("%s",str)!=EOF)
    {
        int i,len;
        int sum=0;
        int xiaoxie=0,daxie=0,hunhe=0;
        int shuzi=0,fuhao=0;
        int zimu=0;
        len=strlen(str);
        if(len<=4)
        {
            sum=sum+5;
        }
        else if(len>4&&len<=7)
        {
            sum=sum+10;
        }
        else if(len>=8)
        {
            sum=sum+25;
        }
        for(i=0;i<len;i++)
        {
            if(str[i]<='z'&&str[i]>='a')
            {
                xiaoxie=1;
            }
            else if(str[i]<='Z'&&str[i]>='A')
            {
                daxie=1;
            }
            else if(str[i]>='0'&&str[i]<='9')
            {
                shuzi++;
            }
            else if((str[i]>='!' && str[i] <='/') || (str[i]>=':' && str[i] <='@') ||
                     (str[i]>='[' && str[i] <='`') || (str[i]>='{' && str[i] <='~'))
            {
                fuhao++;
            }
        }
        if(xiaoxie==1||daxie==1){
            zimu=1;
        }
        if(xiaoxie==0&&daxie==0){
            sum=sum+0;
        }
        else if((xiaoxie==1&&daxie==0)||(xiaoxie==0&&daxie==1)){
            sum=sum+10;
        }
        else if(xiaoxie==1&&daxie==1){
            sum=sum+20;
        }
        if(shuzi==0){
            sum=sum+0;
        }
        else if(shuzi==1){
            sum=sum+10;
        }
        else if(shuzi>1){
            sum=sum+20;
        }
        if(fuhao==0){
            sum=sum+0;
        }
        else if(fuhao==1){
            sum=sum+10;
        }
        else if(fuhao>1){
            sum=sum+25;
        }
        if(zimu==1&&shuzi>0&&fuhao==0){
            sum=sum+2;
        }
        else if((xiaoxie==1&&daxie==0&&shuzi>0&&fuhao>0)||(xiaoxie==0&&daxie==1&&shuzi>0&&fuhao>0)){
            sum=sum+3;
        }
        else if(daxie==1&&xiaoxie==1&&shuzi>0&&fuhao>0){
            sum=sum+5;
        }
        if(sum>=90){
            printf("VERY_SECURE\n");
        }
        else if(sum>=80&&sum<90){
            printf("SECURE\n");
        }
        else if(sum>=70&&sum<80){
            printf("VERY_STRONG\n");
        }
        else if(sum>=60&&sum<70){
            printf("STRONG\n");
        }
        else if(sum>=50&&sum<60){
            printf("AVERAGE\n");
        }
        else if(sum>=25&&sum<50){
            printf("WEAK\n");
        }
        else{
            printf("VERY_WEAK\n");
        }
        sum=0;
    }
}

89 扑克牌大小

描述
扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如:4 4 4 4-joker JOKER。
请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。
基本规则:
(1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
(3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;

(4)输入的两手牌不会出现相等的情况。

数据范围:字符串长度:
输入描述:
输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如 4 4 4 4-joker JOKER。

输出描述:
输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。

示例1
输入:
4 4 4 4-joker JOKER

输出:
joker JOKER
代码

#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;

//用哈希表记录每个字符相应的大小,其中10用字符1表示
unordered_map<char, int> nums{{'3', 1},{'4', 2}, {'5', 3}, {'6', 4}, {'7', 5}, 
{'8', 6}, {'9', 7}, {'1', 8},{'J', 9}, {'Q', 10}, {'K', 11}, {'A', 12}, {'2', 13}};

int main(){
    string s;
    while(getline(cin, s)){
        string s1_origin = s.substr(0, s.find('-')); //从-处截取成两段
        string s2_origin = s.substr(s.find('-') + 1);
        string s1 = "", s2 = "";
        for(int i = 0; i < s1_origin.length(); i++) //将原字符串中的10变成1
            if(s1_origin[i] != '0')
                s1 += s1_origin[i];
        for(int i = 0; i < s2_origin.length(); i++) //将原字符串中的10变成1
            if(s2_origin[i] != '0')
                s2 += s2_origin[i];
        if(s1 == "joker JOKER" || s2 == "joker JOKER") //如果有王炸直接输出王炸
            cout << "joker JOKER";
        else if(s1.length() == 7 && s2.length() == 7){ //字符串长度都为7,说明两个都是炸弹
            if(nums[s1[0]] > nums[s2[0]]) //比较炸弹大小
                cout << s1_origin << endl;
            else
                cout << s2_origin << endl;
        }else if(s1.length() == 7) //字符串其中一个为7,说明一个是炸弹,输出炸弹
            cout << s1_origin << endl;
        else if(s2.length() == 7)
            cout << s2_origin << endl;
        else if(s1.length() == s2.length()){ //没有炸弹的情况下相同类型才能比较
            if(nums[s1[0]] > nums[s2[0]]) //个子、对子、三个、顺子都是比较第一个大小
                cout << s1_origin << endl;
            else
                cout << s2_origin << endl;
        }
        else //无法比较
            cout << "ERROR" << endl;
    }
}

90 24点运算

描述
计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:

3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER

本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。

详细说明:
1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,没有括号,友情提醒,整数除法要当心,是属于整除,比如2/3=0,3/2=1;
2.牌面210对应的权值为210, J、Q、K、A权值分别为为11、12、13、1;
3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
4.输出的算式格式为4张牌通过±/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;
5.输出算式的运算顺序从左至右,不包含括号,如1+2+3
4的结果为24,2 A 9 A不能变为(2+1)*(9-1)=24
6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
7.因为都是扑克牌,不存在单个牌为0的情况,且没有括号运算,除数(即分母)的数字不可能为0

数据范围:一行由4张牌组成的字符串
输入描述:
输入4张牌为字符串形式,以一个空格隔开,首尾无空格;

输出描述:
输出怎么运算得到24,如果无法得出24,则输出“NONE”表示无解,如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
示例1
输入:
A A A A

输出:
NONE

说明:
不能实现
代码

#include <stdio.h>
#include <string.h>
int calc(int num1, int num2, int key){
    int ret = 0;
    if(key == 1){
        ret = num1*num2;
        return ret;
    }
    if(key == 2 && num2!=0){
        ret = num1/num2;
        return ret;
    }else if(key == 2 && num2==0){
        return 0;
    }
    if(key == 3){
        ret = num1+num2;
        return ret;
    }
    if(key == 4){
        ret = num1-num2;
        return ret;
    }
    return 0;
}

int strToint(char x){
    if(x == 'J'){
        return 11;
    }
    if(x == 'Q'){
        return 12;
    }
    if(x == 'K'){
        return 13;
    }
    if(x == 'A'){
        return 1;
    }
    if(x == '3'){
        return 3;
    }
    if(x == '4'){
        return 4;
    }
    if(x == '5'){
        return 5;
    }
    if(x == '6'){
        return 6;
    }
    if(x == '7'){
        return 7;
    }
    if(x == '8'){
        return 8;
    }
    if(x == '9'){
        return 9;
    }
    if(x == 'X'){
        return 10;
    }
    if(x == '2'){
        return 2;
    }
    return 0;
}
char inttoStr(int x){
    if(x == 11){
        return 'J';
    }
    if(x == 12){
        return 'Q';
    }
    if(x == 13){
        return 'K';
    }
    if(x == 1){
        return 'A';
    }
    if(x == 3){
        return '3';
    }
    if(x == 4){
        return '4';
    }
    if(x == 5){
        return '5';
    }
    if(x == 6){
        return '6';
    }
    if(x == 7){
        return '7';
    }
    if(x == 8){
        return '8';
    }
    if(x == 9){
        return '9';
    }
    if(x == 10){
        return 'X';
    }
    if(x == 2){
        return '2';
    }
    return 0;
}
int inputCheck(char str[]){
    if(strlen(str)!=7){
        //printf("ok");
        return 1;
    }
    //printf("ok");
    return 0;
}

char numtoOper(int nums){
    if(nums == 1){
        return '*';
    }
    if(nums == 2){
        return '/';
    }
    if(nums == 3){
        return '+';
    }
    if(nums == 4){
        return '-';
    }
    return 0;
} 

void is24(int tempret3, int nums[], int i, int j, int a, int map[], char outstr[], char myIntToStr[], char stroper[]){
           for(int x = 0;x<4;x++){
               myIntToStr[x] = inttoStr(nums[map[x]]);
              }
           for(int y = 0;y<3;y++){
                 if(y == 0){
                    stroper[y] = numtoOper(i);
                   }
                 if(y == 1){
                    stroper[y] = numtoOper(j);
                   }
                 if(y == 2){
                     stroper[y] = numtoOper(a);
                   }
              }
    
             outstr[0] = myIntToStr[0];
                    //printf("%c", nums[map[0]]);
             outstr[1] = stroper[0];
                    //printf("%c", str[0]);
             outstr[2] = myIntToStr[1];
                    //printf("%c", str[0]);
             outstr[3] = stroper[1];
                    //printf("%c", str[0]);
             outstr[4] = myIntToStr[2];
                    //printf("%c", str[0]);
             outstr[5] = stroper[2];
                    //printf("%c", str[0]);
             outstr[6] = myIntToStr[3];
             //printf("%c", str[0]);
}
int mapcali(int nums[], int map [], char outstr[], char myIntToStr[], char stroper[]){
    int tempret1 = 0;
    int tempret2 = 0;
    int tempret3 = 0;
   // printf("mapcaliok");
    for(int i = 1;i<5;i++){
        for(int j = 1;j<5;j++){
            for(int a = 1;a<5;a++){
                tempret1 = calc(nums[map[0]], nums[map[1]], i);
                tempret2 = calc(tempret1, nums[map[2]], j);
                tempret3 = calc(tempret2, nums[map[3]], a);
                if(tempret3 == 24){
                    is24(tempret3, nums, i, j, a, map, outstr, myIntToStr, stroper);
                    return 1;
                }
                
            }
        }
    }
    
    return 0;
}

int cali(int nums[], int map[], char outstr[], char myIntToStr[], char stroper[]){
    for(int i = 0;i<4;i++){
        map[0] = i;
        for(int j = 0;j<4;j++){
            if(i!= j){
             map[1] = j;
             for(int a = 0;a<4;a++){
             if(a!=i && a!= j){
                 map[2] = a;
                 map[3] = 6-a-i-j;
                 //printf("okok");
                 int ret = mapcali(nums, map, outstr, myIntToStr, stroper);
                     if(ret==1){
                         return 1;
                     }
                 }
              }
            }
        }
    }
    return 0;
}
int test(int nums []){
    printf("%d", nums[2]);
    return 0;
}
int main(){
    int nums [4];
    int map[4];
    char tempstr[20];
    int ret = 0;
    int calcret;
    char str[7];
    int tempcnt = 0;
    
    char outstr [7];
    char myIntToStr[4];
    char stroper[3];
    
    gets(tempstr);
    if(inputCheck(tempstr)){
            ret = 3;
     }else{
         for(int t = 0;t<7;t++){
             if(tempstr[t]!=' '){
                 str[tempcnt] = tempstr[t];
                 nums [tempcnt] = strToint(str[tempcnt]);
                 tempcnt++;
             }
            }
        }
    
    if(ret!=3){
       calcret = cali(nums, map, outstr, myIntToStr, stroper);
       if(calcret==1){
            ret = 2;
        }else{
           ret = 1;
       }
    }
    
    
    if(ret == 3){
        printf("ERROR");
    }else if(ret == 1){
        printf("NONE");
    }else if(ret == 2){
        //printf("2");
        for(int i = 0;i<7;i++){
            if(outstr[i] == 'X'){
                printf("10");
            }else{
               printf("%c", outstr[i]);
            }
        }
    }else if(ret == 0){
        printf("fail");
    }
   return 0;
}

91 合法IP

描述
IPV4地址可以用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此正号不需要出现),如10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。

现在需要你用程序来判断IP是否合法。

注意本题有多组样例输入。
数据范围:数据组数:
进阶:时间复杂度:,空间复杂度:

输入描述:
输入一个ip地址,保证不包含空格

输出描述:
返回判断的结果YES or NO

示例1
输入:
10.138.15.1
255.0.0.255
255.255.255.1000

输出:
YES
YES
NO
代码

#include<iostream>
#include<string>
#include<sstream>
using namespace std;

int main(){
    string ip;
    while(getline(cin, ip)){
        stringstream ss;
        ss << ip;
        unsigned a, b, c, d;
        char c1, c2, c3; //接收点
        ss >> a >> c1 >> b >> c2 >> c >> c3 >> d; //流输出数组和字符
        //判断数字范围
        if(a >= 0 && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0 && d <= 255)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

92 走方格的方案数

描述
请计算n*m的棋盘格子(n为横向的格子数,m为竖向的格子数)从棋盘左上角出发沿着边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。
注:沿棋盘格之间的边缘线行走
本题含有多组样例输入。
数据范围:

输入描述:
每组样例输入两个正整数n和m,用空格隔开。(1≤n,m≤8)
输出描述:
每组样例输出一行结果
示例1
输入:
2 2
1 2
输出:
6
3
思想
使用递归思想,如果都为0,则只有一种;
如果都为1,则有两种路径。
代码

#include<stdio.h>

int comPu(int n,int m)
{
    if(0 == n || 0 == m)    return 1;
    if(1 == n && 1 == m)    return 2;
    return comPu(n-1, m) + comPu(n, m-1);
}

int main()
{
    int n,m;
    while(EOF !=scanf("%d%d",&n,&m))
    {
        printf("%d\n",comPu(n, m));
    }
    
    return 0;
}

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

描述
输入一个字符串,返回其最长的数字子串,以及其长度。若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置)
本题含有多组样例输入。

数据范围:字符串长度, 保证每组输入都至少含有一个数字
输入描述:
输入一个字符串。1<=len(字符串)<=200

输出描述:
输出字符串中最长的数字字符串和它的长度,中间用逗号间隔。如果有相同长度的串,则要一块儿输出(中间不要输出空格)。

示例1
输入:
abcd12345ed125ss123058789
a8a72a6a5yy98y65ee1r2

输出:
123058789,9
729865,2

说明:
样例一最长的数字子串为123058789,长度为9
样例二最长的数字子串有72,98,65,长度都为2
代码
C语言解法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 205
typedef struct{
    char *pa;
    int num;
}Number;
int main()
{
    char str[SIZE]={'\0'};
    while(fgets(str,SIZE,stdin)!=NULL){
        char *p=strchr(str,'\n');
        *p='\0';
        Number trace[200];
        int i,j,k=1,h=0,len=strlen(str),maxlen=0;
        for(i=0;i<len;){
            if(str[i]>='0'&&str[i]<='9'){
                trace[h].pa=&str[i];
                for(j=i;j<len;j++){
                    if(str[j+1]>='0'&&str[j+1]<='9'){
                        k++;
                    }
                    else{
                        maxlen=maxlen>k?maxlen:k;
                        i+=k;
                        break;
                    }
                }
                trace[h++].num=k;
                k=1;
            }
            else{
                i++;
            }
        }
        for(i=0;i<h;i++){
            if(trace[i].num==maxlen){
                for(j=0;j<maxlen;j++){
                    printf("%c",*(trace[i].pa+j));
                }
            }
        }
        printf(",%d\n",maxlen);
    }
}

94 数组分组(不懂题意)

描述
输入int型数组,询问该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),不是5的倍数也不是3的倍数能放在任意一组,可以将数组分为空数组,能满足以上条件,输出true;不满足时输出false。

本题含有多组样例输入。

数据范围:每个数组大小满足 ,输入的数据大小满足
输入描述:
第一行是数据个数,第二行是输入的数据

输出描述:
返回true或者false

示例1
输入:
4
1 5 -5 1
3
3 5 8

输出:
true
false

说明:
第一个样例:
第一组:5 -5 1
第二组:1
第二个样例:由于3和5不能放在同一组,所以不存在一种分法。
示例2
输入:
2
8 -8
输出:
true

说明:
由于可以将数组分为空数组,所以输出true。
代码

#include <stdio.h>
int dfs(int *in,int len,int five,int three){
    if((len==0)&&(five==three)) return 1;
    else if((len==0)&&(five!=three)) return 0;
    int next[len-1];
    for(int i=0;i<len;i++){
        for(int j=0;j<len-1;j++){
            if(j<i) next[j]=in[j];
            else if(j>=i) next[j]=in[j+1];
        }
        if(dfs(next,len-1,five+in[i],three)) return 1;
        if(dfs(next,len-1,five,three+in[i])) return 1;
    }
    return 0;
}
int main(){
    int five,three,n,i,tem,len;

    while (scanf("%d",&n)!=-1){
        int input[n];
        five=0;
        three=0;
        len=0;
        for(i=0;i<n;i++){
            scanf("%d",&tem);
            if(tem%5==0) five+=tem;
            else if(tem%3==0) three+=tem;
            else{
                input[len]=tem;
                len++;
            }
        }
        int total=0;
        for(i=0;i<len;i++) total+=input[i];
        if(((total+five+three)%2==0)&&(dfs(input,len, five, three))) printf("true\n");
        else printf("false\n");
    }
    return 0;
}

95 记票统计

描述
请实现一个计票统计系统。你会收到很多投票,其中有合法的也有不合法的,请统计每个候选人得票的数量以及不合法的票数。
本题有多组样例输入。

数据范围:每组输入中候选人数量满足 ,总票数量满足
输入描述:
输入候选人的人数n,第二行输入n个候选人的名字(均为大写字母的字符串),
第三行输入投票人的人数,第四行输入投票。
输出描述:
按照输入的顺序,每行输出候选人的名字和得票数量,最后一行输出不合法的票数。
示例1
输入:
4
A B C D
8
A D E CF A GG A B

输出:
A : 3
B : 1
C : 0
D : 1
Invalid : 3

代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct Candidate
{
    char * name[20];
    int cnt;
}Candidate;

int main()
{
    int candidates_num = 0, vote_num = 0;
    while(scanf("%d", &candidates_num) != EOF)
    {
        Candidate *candidate = (Candidate *)malloc(sizeof(Candidate) * candidates_num);
        for(int i=0; i<candidates_num; i++)
        {
            scanf("%s", candidate[i].name);
            candidate[i].cnt = 0;
        }
        scanf("%d", &vote_num);
        char temp[20] = {'\0'};     //存储投票
        int invalid = 0;            //统计非法投票人数
        for(int i=0; i<vote_num; i++)
        {
            scanf("%s", temp);
            int flag = 0;
            for(int j=0; j<candidates_num; j++)
            {
                if(strcmp(temp, candidate[j].name) == 0)
                {
                    candidate[j].cnt++;
                    flag = 1;
                }
            }
            if(!flag) invalid++;
        }
        for(int i=0; i<candidates_num; i++)
        {
            printf("%s : %d\n", candidate[i].name, candidate[i].cnt);
        }
        printf("Invalid : %d\n", invalid);
        free(candidate);
    }
    return 0;
}

96 人民币转换

描述
考试题目和要点:

1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。

2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。

3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如6007.14,应写成“人民币陆仟零柒元壹角肆分“。
4、10应写作“拾”,100应写作“壹佰”。例如,1010.00应写作“人民币壹仟零拾元整”,110.00应写作“人民币壹佰拾元整”
5、十万以上的数字接千不用加“零”,例如,30105000.00应写作“人民币叁仟零拾万伍仟元整”

本题含有多组样例输入。

输入描述:
输入一个double数

输出描述:
输出人民币格式

示例1
输入:
151121.15
10012.02
13.64
0.85

输出:
人民币拾伍万壹仟壹佰贰拾壹元壹角伍分
人民币壹万零拾贰元贰分
人民币拾叁元陆角肆分
人民币捌角伍分

示例2
输入:
1010.00
110.00

输出:
人民币壹仟零拾元整
人民币壹佰拾元整
代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct CH Ch;
struct CH
{
    char ch[4];
    Ch *next;
    /* data */
};
int main()
{
    char number[10][4] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    char unit[11][4] = {"分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"};
    // char unit[13][4] = {"","","分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"};
    char integer[4] = "整";
    long long num = 0;
    double value;
    int position;
    int zero = 0;
    int posnum = 0;
    Ch *ptr = 0;
    Ch *header = 0;
    while (scanf("%lf", &value) != EOF)
    {
        position = 0;
        // position = 2;
        // 不加会变成0.28
        num = (value + 0.0001) * 100;
        zero = 0x02;
        while (num)
        {
            // 上一个非0,当前不是起始位,方可输出0
            // 不是十位方可输出1
            // 当前是起始位,或当前位不为0方可输出单位
            if (!header && position > 1)
            {
                ptr = (Ch *)malloc(sizeof(Ch));
                ptr->next = header;
                header = ptr;
                strcpy(ptr->ch, "整");
            }
            posnum = num % 10;
            if ((0x01 & zero) || posnum)
            {
                ptr = (Ch *)malloc(sizeof(Ch));
                ptr->next = header;
                header = ptr;
                strcpy(ptr->ch, unit[position]);
            }
            if (posnum == 0)
            {
                if (!zero && position > 1)
                {
                    ptr = (Ch *)malloc(sizeof(Ch));
                    ptr->next = header;
                    header = ptr;
                    strcpy(ptr->ch, number[posnum]);
                }
            }
            else if (posnum == 1)
            {
                if (position != 3 && position != 7)
                {
                    ptr = (Ch *)malloc(sizeof(Ch));
                    ptr->next = header;
                    header = ptr;
                    strcpy(ptr->ch, number[posnum]);
                }
            }
            else
            {
                ptr = (Ch *)malloc(sizeof(Ch));
                ptr->next = header;
                header = ptr;
                strcpy(ptr->ch, number[posnum]);
            }
            num /= 10;
            position++;
            if (posnum)
            {
                zero &= 0xfd;
            }
            else
            {
                zero |= 0x02;
            }
            if ((position + 2) % 4 == 0)
            {
                zero |= 0x01;
            }
            else
            {
                zero &= 0xfe;
            }
        }
        printf("人民币");
        while (header)
        {
            ptr = header->next;
            printf("%s", header->ch);
            free(header);
            header = ptr;
        }
        printf("\n");
    }
    return 0;
}

97 表示数字

描述
将一个字符中所有的整数前后加上符号“*”,其他字符保持不变。连续的数字视为一个整数。

注意:本题有多组样例输入。

数据范围:字符串长度满足
输入描述:
输入一个字符串

输出描述:
字符中所有出现的数字前后加上符号“*”,其他字符保持不变

示例1
输入:
Jkdi234klowe90a3
5151

输出:
Jkdi234klowe90a3
5151
代码

#include <stdio.h>
int shuzi(char c){
    if((c>='0')&&(c<='9')) return 1;
    return 0;
}

int main(){
    char str[1000];
    int len,i,shuf;
    
    while(scanf("%s",str)!=-1){
        len=strlen(str);
        shuf=0;
        if(shuzi(str[0])){
            printf("*");
            shuf=1;
        }
        for (i=0;i<len;i++){
            if(shuf){
                if(shuzi(str[i])){}
                else {
                    printf("*");
                    shuf=0;
                }
            }
            else{
                if(shuzi(str[i])){
                    printf("*");
                    shuf=1;
                }
            }
            printf("%c",str[i]);
        }
        if(shuzi(str[len-1])) printf("*");
        printf("\n");
        
    }
    
    return 0;
}

98 记负均正

描述
首先输入要输入的整数个数n,然后输入n个整数。输出为n个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。
0即不是正整数,也不是负数,不计入计算

数据范围: ,输入的整数都满足
输入描述:
本题有多组输入用例。
首先输入一个正整数n,
然后输入n个整数。

输出描述:
输出负数的个数,和所有正整数的平均值。

示例1
输入:
5
1 2 3 4 5
10
1 2 3 4 5 6 7 8 9 0

输出:
0 3.0
0 5.0

示例2
输入:
3
0 0 0

输出:
0 0.0
代码

#include<stdio.h>
#include<math.h>
int main()
{
    int num;
    int a[1000];
    while(scanf("%d",&num)!=EOF)
    {
        int count = 0;
        int countint =0;
        float sum = 0;
        for(int i =0;i<num;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]<0)
            {
                count++;
            }
            if(a[i]>0)
            {
                countint++;
                sum+=a[i];
            }
        }
        printf("%d %0.1f\n",count,sum/countint);
    }
}

感谢阅读,祝君成功!
-by aiziyou

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack.Jia

感谢打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值