oj习题

以下oj练习均独立完成
统计单词:
编一个程序,读入用户输入的,以“.”结尾的一行文字,统计一共有多少个单词,并分别输出每个单词含有多少个字符。 (凡是以一个或多个空格隔开的部分就为一个单词)
#include<stdio.h>
int main(){
    int i=0;
    int wordcount=0;
    char arr[1000];
    
    while(gets(arr)!=NULL){
        while(arr[i]!='.'){
            if(arr[i]!=' '){
                wordcount++;
                i++;
            }else{
                if(arr[i-1]!=' '){//防连续空格
                    printf("%d",wordcount);

                    printf(" ");

                    wordcount=0;
                    i++;
                }else{
                    i++;
                }
            }      
        }
        printf("%d",wordcount);
    }
    return 0;
}

ip地址:
输入一个ip地址串,判断是否合法。

#include<stdio.h>
#include<stdlib.h>    //atoi
#include<malloc.h>    //malloc
#include<string.h>    //strcpy、strncpy
int main(){
    int i=0;int j=0;
    char arr[50];char *IP[4];//定义字符串指针数组,用于存四块ip
    while(scanf("%s",arr)!=EOF){
        while(arr[i]!='\0'){
            if(arr[i]=='.'){
                IP[j]=(char*)malloc((i+1)*sizeof(char));//为指针分配内存空间
                
                strncpy(IP[j],arr,i);//复制arr字符数组的前i个字符到ip字符数组中,strcpy参数是字符串指针,atoi函数也是。
                strcpy(arr,arr+i+1);//将剩下的字符串覆盖之前的字符串
                i=0;//并令i=0重新开始判断
                j++;
            }else{
            i++;
            }
       }
        IP[j]=(char*)malloc((i+1)*sizeof(char));//处理最后一个ip块
        strncpy(IP[j],arr,i);
        //printf("%d.%d.%d.%d\n",atoi(IP[0]),atoi(IP[1]),atoi(IP[2]),atoi(IP[3]));
        if((atoi(IP[0]))>=0 && (atoi(IP[0]))<=255 && (atoi(IP[1]))>=0 && (atoi(IP[1]))<=255 && (atoi(IP[2]))>=0 && (atoi(IP[2]))<=255 && (atoi(IP[3]))>=0 && (atoi(IP[3]))<=255){            
            printf("Yes!");
        }else{
            printf("No!");
        }
    }
    return 0;
}

二叉排序树:
二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树: 1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值; 2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值; 3. 左、右子树本身也是一颗二叉排序树。 现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。 

例子输入:
5
2 5 1 3 4

输出:
-1
2
2
5
3
插入节点时加个递归
#include<stdio.h>
#include<malloc.h>

struct Node{
    int key;
    struct Node *right;
    struct Node *left;
    struct Node *parent;
};
typedef struct Node BitNode;
typedef struct Node *BitTree;

void insertnode(int data,BitTree keynode){
    BitTree m;
    if(data==keynode->key){printf("关键字已经存在!!");return;} //判断一下节点是否存在,存在则直接返回
    else if(data<keynode->key){//判断要插入的data比目前这个节点的关键字小,则往左边插
        if(keynode->left!=NULL){ //左边不为空就继续比较
            insertnode(data,keynode->left);
        }else{
            m=(BitTree)malloc(sizeof(BitNode));//为空,则插
            m->key=data;
            m->right=NULL;
            m->left=NULL;
            m->parent=keynode;
            printf("%d\n",keynode->key);//输出父节点关键字
            keynode->left=m;
        }
    }else if(data>keynode->key){
        if(keynode->right!=NULL){
            insertnode(data,keynode->right);
        }else{
            m=(BitTree)malloc(sizeof(BitNode));
            m->key=data;
            m->right=NULL;
            m->left=NULL;
            m->parent=keynode;
            printf("%d\n",keynode->key);
            keynode->right=m;
        }
    }
    return;
}

void freespace(BitTree keynode){
    while(keynode){
        if(keynode->left==NULL && keynode->right==NULL){
            free(keynode);
        }else{
            freespace(keynode->right);
            freespace(keynode->left);
        }
    }
    
}
  

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        BitTree head;
        int d[100];
        int data;int i=0;
        for(i=0;i<n;i++){
            scanf("%d",&d[i]);  //存一下按序输入的节点关键字,也可以直接在下面for循环里输入
        }
        for(i=0;i<n;i++){
            data=d[i];
            if(i==0){ //第一个节点
                head=(BitTree)malloc(sizeof(BitNode));
                head->key=data;
                printf("-1\n");
                head->right=NULL;
                head->left=NULL;
                head->parent=NULL;
            }else{ //后面的节点就开始插入
                insertnode(data,head);
            }
        }
        //freespace(head);
    }
    return 0;
}


字符串连接
不借用任何字符串库函数实现无冗余地接受两个字符串,然后把它们无冗余的连接起来。

输入描述:

每一行包括两个字符串,长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据,
不借用任何字符串库函数实现无冗余地接受两个字符串,然后把它们无冗余的连接起来。
输出连接后的字符串。

要实现字符串无冗余即一个一个读取字符,动态扩充内存连接字符,碰到回车符认为一组数据输入完毕,补上结束符打印输出,暂时不知道怎么样书写进行多数据测试

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

int main(){
    char a;//用于接收一个一个的字符
    char *d;//用于动态分配内存,连接字符
    d=NULL;
    int j=0;//用j来指示合并后的字符串的大小
    while((a=getchar())!='\n'){
        if(a!=' '){
            j++;
            d=(char*)realloc(d,sizeof(char)*(1+j)); //多分配一个内存空间,用于循环结束后添加结束符'\0'
            *(d+j-1)=a;
        }
    }
    *(d+j)='\0';
    printf("%s\n",d);
    return 0;
}


a+b
实现一个加法器,使其能够输出a+b的值。

输入描述:

输入包括两个数a和b,其中a和b的位数不超过1000位。

输出描述:

可能有多组测试数据,对于每组数据,
输出a+b的值。
求大数和,由于位数得限制,只能用char型数组来存,并计算
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
    char a[10001];char b[10001];char sum[10001];
    int i=0;int j=0;int k=0;int c=0;
    int lena;int lenb;int lensum;
    while(scanf("%s%s",a,b)!=EOF){
        memset(sum,0,1000);
        lena=strlen(a);i=lena-1; 
        lenb=strlen(b);j=lenb-1; //得到两个数字字符串得位数长度
        if(lena>lenb){
            k=lena;
        }else{
            k=lenb;
        }
        lensum=k;                //得到两个位数中最长的作为最后结果的长度,并多存一位防止进位
        while(i>=0 && j>=0){     //从最低位开始相加两个字符数组的每一位,并把每一位对应存储到sum
            sum[k]=a[i]+b[j]-'0'+c;
            c=0;
            if(sum[k]>'9'){
                sum[k]=sum[k]-10;
                c=1;
            }
            k--;
            i--;
            j--;
        }
        
        while(i>=0){             //b字符数组存储完毕,a字符数组还有高位需要存储到sum中
            sum[k]=a[i]+c;
            c=0;
            if(sum[k]>'9'){
                sum[k]=sum[k]-10;
                c=1;
            }
            k--;
            i--;
        }
        
        while(j>=0){            //a字符数组存储完毕,b字符数组还有高位需要存储到sum中
            sum[k]=b[j]+c;
            c=0;
            if(sum[k]>'9'){
                sum[k]=sum[k]-10;
                c=1;
            }
            k--;
            j--;
        }
		
        if(c==1){               //如果最高位存储后还有进位
            sum[k]='1';         //有进位把最高位令为1字符
            c=0;
        }else{
            sum[k]='0';             //无进位把最高位令为0字符
        }
        if(sum[k]=='0'){
			
            puts(sum+1); //如果没有进位第一位预留空间为0,则从第二个地址开始输出
        }else{
            puts(sum);  //如果有进位,则全部输出
        }
    }
	return 0;

}


排序

对输入的n个数进行排序并输出。

输入描述:

    输入的第一行包括一个整数n(1<=n<=100)。
    接下来的一行包括n个整数。

输出描述:

    可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有一个空格。
    每组测试数据的结果占一行。

快排:
#include<stdio.h>

void patition(int data[],int left,int right){
    if(left>=right){
        return;
    }
        int division=data[left];
        int j=left;
        int i=right;
        while(i>=j){
            while(division<=data[i] && i>=j){
                i--;
            }
            data[j]=data[i];j++;
            while(division>=data[j] && i>=j){
                j++;
            }
            data[i]=data[j];i--;
        }
        data[i]=division;
    
        patition(data,left,i-1);
        patition(data,i+1,right);
}

int main(){
    int n;int d[100];
    int i;
    int j;
    while(scanf("%d",&n)!=EOF){
            for(i=0;i<n;i++){
                scanf("%d",&d[i]);
            }
            patition(d,0,n-1);

        for(j=0;j<n;j++){
            printf("%d",d[j]);
            if(j!=n-1){
                printf(" ");
            }
        }
    }
    return 0;
}

快排无法通过oj:运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。

冒泡、直插、:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){ 
    int n;int d[100]; 
    int i; 
    int j; 
    int tmp; 
    while(scanf("%d",&n)!=EOF){ 
        memset(d,0,100*sizeof(int)); 
        for(i=0;i<n;i++){ 
            scanf("%d",&d[i]);                //输入 
    } 

    /*//冒泡 
    for(i=0;i<n;i++){ 
        for(j=0;j<n-i-1;j++){ 
            if(d[j]>d[j+1]){ 
                tmp=d[j]; 
                d[j]=d[j+1]; 
                d[j+1]=tmp; 
            } 
        } 
    }*/        
    /*//直插排序        
    for(i=1;i<n;i++){  
    //注意备份一下当前插入值            
        tmp=d[i];            
        for(j=i-1;j>=0;j--){                
            if(tmp<d[j]){                    
                d[j+1]=d[j];                
            }else{                    
                break; //当tmp比当前j要大则很明显,已经找到合适的位置了,直接跳出来                
            }            
        }            
        d[j+1]=tmp;        
    }*/        /*//简单选择排序        
    int min=0;        
    for(i=0;i<n;i++){            
        tmp=d[i];           
        //令每次循环的第一个为最小的,然后去比较            
        min=i;            
        for(j=i;j<n;j++){//选最小的                
            if(d[j]<tmp){                    
                tmp=d[j];                    
                min=j;                
            }            
        }            
        if(min!=i){                
            tmp=d[i];                
            d[i]=d[min];        
            //把最小的数放到循环的第一个元素中               
            d[min]=tmp;            
        }        
    }*/

    for(j=0;j<n;j++){ 
        printf("%d",d[j]);                //输出 
        printf(" "); 
        if(j==n-1){ 
            printf("\n"); 
        } 
    } 
    
    return 0;
}

特殊排序

题目描述

输入一系列整数,将其中最大的数挑出,并将剩下的数进行排序。

输入描述:

输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数。
接下来的一行有N个整数。

输出描述:

可能有多组测试数据,对于每组数据,
第一行输出一个整数,代表N个整数中的最大值,并将此值从数组中去除,将剩下的数进行排序。
第二行将排序的结果输出。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void adjustdown(int data[],int k,int len){
    int i;
    data[0]=data[k];   //堆排序k不能为0
    for(i=2*k;i<=len;i*=2){
        if((data[i]<data[i+1])&&(i+1<=len)){
            i++;
        }
        if(data[0]>=data[i]){
            break;
        }else{
            data[k]=data[i];
            k=i;
        }
    }
    data[k]=data[0];
}

void buildmaxheap(int data[],int len){
    int i;
    for(i=len/2;i>0;i--){
        adjustdown(data,i,len);
    }
}

void swap(int *a,int *b){
    int tmp;
    tmp=*a;
    *a=*b;
    *b=tmp;
}

void heapsort(int data[],int len){
    int i;
    buildmaxheap(data,len);
    for(i=len;i>1;i--){//当只剩下一个元素时,不用调整了,而且下面的函数需要i-1,即i>1
        swap(&data[1],&data[i]);
        adjustdown(data,1,i-1);
    }
}

int main(){
    int n;int data[1000];
    int i;
    int j;
    int max;
    while(scanf("%d",&n)!=EOF){//输入
        memset(data,0,1000*sizeof(int));
        for(i=1;i<=n;i++){
            scanf("%d",&data[i]);
        }
        //一、
        //剔除最大值,存到max
        
        //排序
        
        
        /*//二、简单选择排序、选最大的
        int mtmp=0;int tmp=0;
        for(i=n-1;i>=0;i--){
            max=data[i];
            mtmp=i;
            for(j=i;j>=0;j--){
                if(data[j]>max){
                    max=data[j];
                    mtmp=j;
                }
            }
            if(mtmp!=i){
                tmp=data[i];
                data[i]=data[mtmp];
                data[mtmp]=tmp;
            }
        }
        max=data[n-1];
        data[n-1]=-1;*/
        
        //三、堆排序、大顶堆,要求输入从1开始到n,不能存在第0项
        heapsort(data,n);
        max=data[n];
        data[n]=-1;
        //输出
        
        printf("%d\n",max);
        if(n==1){
            printf("%d",data[n]);
        }else{
            for(i=1;i<n;i++){
                printf("%d",data[i]);
                if(i!=n-1){
                    printf(" ");
                }
            }
        }
        
    }
    return 0;
}

二叉树遍历:

题目描述

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

输入描述:

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

输出描述:

输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。
 
  
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//思路一、先建立树,再输出后序
struct Node{
    char key;
    struct Node *left;
    struct Node *right;
};
typedef struct Node BitNode,*BitTree;

char preorder[26];
char inorder[26];

BitTree buildTree(int prebegin,int preend,int inbegin,int inend){
    int i;int index=0;

    BitTree p=(BitTree)malloc(sizeof(BitNode));
    p->key=preorder[prebegin];
    
    for(i=inbegin;i<=inend;i++){
        if(preorder[prebegin]==inorder[i]){
            index=i;
            break;
        }
    }
    
    if(index!=inbegin){
        p->left=buildTree(prebegin+1,prebegin+index-inbegin,inbegin,index-1);
    }
    
    if(index!=inend){
        p->right=buildTree(prebegin+index-inbegin+1,preend,index+1,inend);
    }
    return p;
}

void postorder(BitTree p){
    if(p->left!=NULL){
        postorder(p->left);
    }
    if(p->right!=NULL){
        postorder(p->right);
    }
        printf("%c",p->key);
}

int main(){
    
    while(scanf("%s%s",preorder,inorder)!=EOF){
        
        int prelen=strlen(preorder);
        int inlen=strlen(inorder);
        BitTree p=buildTree(0,prelen-1,0,inlen-1);
        postorder(p);
        printf("\n");
        
    }
    return 0;
}

//思路二、直接递归输出后序
void posttree(int b1,int e1,int b2,int e2){
    int i;
    for(i=b2;i<=e2;i++){
        if(preorder[b1]==inorder[i]){
            break;
        }
    }
    if(i>b2){
        posttree(b1+1,b1+i-b2,b2,i-1);
    }
    if(i<e2){
        posttree(b1+i-b2+1,e1,i+1,e2);
    }
    printf("%c",preorder[b1]);
    
}

int main(){
    while(scanf("%s%s",preorder,inorder)!=EOF){
        int prelen=strlen(preorder);
        int inlen=strlen(inorder);
        posttree(0,prelen-1,0,inlen-1);
    }
    return 0;
}
奇偶校验

题目描述

输入一个字符串,然后对每个字符进行奇校验,最后输出校验后的二进制数(如'3’,输出:10110011)。

输入描述:

输入包括一个字符串,字符串长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据,
对于字符串中的每一个字符,输出按题目进行奇偶校验后的数,每个字符校验的结果占一行。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int count=0;
int m=0;
void print2(char n,int data[],int level)//将字符的ascii码转换成八位二进制输出到data数组
{
          
        if(level>7){
            return ;
        }

        print2(n>>1,data,level+1);不断右移1位
        data[m]=n&0x1;  //将n与1得到n最右边的一位
        if(data[m]){count++;}
        m++;

}

int main(){
    int data[100];int i;int j;
	int level=0;char ch[100];
	while(scanf("%s",ch)!=EOF){
        int len=strlen(ch);
        for(j=0;j<len;j++){
            m=0;
            count=0;
            memset(data,0,100*sizeof(int));  //每轮循环注意变量的初始化
            print2(ch[j],data,level);
            
            if(count%2==0){
                data[0]=1;
                printf("%d",data[0]);
                for(i=1;i<m;i++){
                    printf("%d",data[i]);
                }
            }else{
                data[0]=0;
                printf("%d",data[0]);
                for(i=1;i<m;i++){
                    printf("%d",data[i]);
                }
            }
            printf("\n");
        }
    }
    return 0;
}


最大的两个数

题目描述

    输入一个四行五列的矩阵,找出每列最大的两个数。

输入描述:

接下来的四行每行包括五个整数。代表一个四行五列的矩阵,矩阵元素全部是整数。

输出描述:

    可能有多组测试数据,对于每组数据,按照样例输出的格式将每列最大的两个数输出,如果最大的两个数中的一个数在这一列中有多个相同的值,则行值取行值小的那一个。
    输出时要保留原矩阵的行列顺序,即在原矩阵中行值小的,在输出矩阵中的行值依然小。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

int main(){
    int data[4][5];
    int i;int j;int k;
    int max;
    int mtmp;
    int secd;
    int stmp;
    while(scanf("%d%d%d%d%d",&data[0][0],&data[0][1],&data[0][2],&data[0][3],&data[0][4])!=EOF){
        for(i=1;i<4;i++){
            for(j=0;j<5;j++){
                scanf("%d",&data[i][j]);//输入
            }
        }
            i=0;
            for(k=0;k<5;k++){  //列循环,找出每列的最大的两个值
                max=data[i][k];//初始化最大值
                mtmp=i;
                for(j=i;j<4;j++){  //找最大值
                    if(data[j][k]>max){
                        max=data[j][k];
                        mtmp=j;
                    }
                }
                if(mtmp!=i){        //初始化第二大的值,避免等于最大值
                    secd=data[i][k];
                    stmp=i;
                }else{
                    secd=data[i+1][k];
                    stmp=i+1;
                }
                for(j=i;j<4;j++){    //找第二大的值,避免与最大值比较
                    if(j==mtmp){
                        continue;
                    }
                    if(data[j][k]>secd){
                        secd=data[j][k];
                        stmp=j;
                    }
                }
                if(mtmp>stmp){         //判断最大值与第二大的值行序列大小,小的赋值到第一行,大的赋值到第二行
                    if(mtmp!=1){
                        data[1][k]=max;
                    }
                    if(stmp!=0){
                        data[0][k]=secd;
                    }
                }else{
                    if(mtmp!=0){
                        data[0][k]=max;
                    }
                    if(stmp!=1){
                        data[1][k]=secd;
                    }
                }
                
            }
        
        for(j=0;j<2;j++){
            for(k=0;k<5;k++){
                printf("%d",data[j][k]);     //输出,这个oj格式要求最后一个数字后没有空格
                if(k!=4){
                    printf(" ");
                }
                
            }
            if(j!=1){
                printf("\n");
            }
        }
    }
    return 0;
}



成绩排序

题目描述

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

输入描述:

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

输出描述:

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

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

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define boolean int
#define True 1
#define False 0
struct student{
    char name[100];
    int age;
    int mark;
};
typedef struct student stunode,*stu;


void swap(stunode *s1,stunode *s2){
    stunode tmp;
    tmp=*s1;
    *s1=*s2;
    *s2=tmp;
}

boolean cmp(stunode s1,stunode s2){          //比较优先判断分数是否相等,若分数不等判断若前面的分数大于后面的分数则返回true,
    if(s1.mark!=s2.mark){                    //若分数相等则判断名字是否相等,若名字不相同判断若前面名字大于后面名字则返回true,
        if(s1.mark>s2.mark){                 //最后判断年龄大小,前者年龄大于后面年龄则返回true
            return True;
        }else{
            return False;
        }
    }
    int tmp=strcmp(s1.name,s2.name);
    if(tmp!=0){
        if(tmp>0){
            return True;
        }else{
            return False;
        }
    }
    if(s1.age>=s2.age){
        return True;
    }else{
        return False;
    }
}

void sort(stunode s[],int begin,int end){ //快排,其中的比较部分用上面写的cmp函数
    if(begin>=end){
        return ;
    }
    int i=begin;int j=end;
    /*
    for(i=0;i<n;i++){
        for(j=0;j<n-i-1;j++){
            if(cmp(s[j],s[j+1])){//s[j]>s[j+1]
                swap(&s[j],&s[j+1]);
            }
        }
    }*/
    stunode tmp=s[begin];
    while(i<j){
        while(cmp(s[j],tmp)&&i<j){
            j--;
        }
        s[i]=s[j];
        while(cmp(tmp,s[i])&&i<j){
            i++;
        }
        s[j]=s[i];
    }
    s[j]=tmp;
    sort(s,begin,i-1);
    sort(s,i+1,end);
}

int main(){
    int n;stunode s[1000];
    int i;int j;
    while(scanf("%d",&n)!=EOF){
        for(i=0;i<n;i++){
            scanf("%s%d%d",&s[i].name,&s[i].age,&s[i].mark);
        }
        sort(s,0,n-1);
        for(j=n-1;j>=0;j--){
            printf("%s %d %d\n",s[j].name,s[j].age,s[j].mark);
        }
    }
    return 0;
}

升序遍历链表

题目描述

建立一个升序链表并遍历输出。

输入描述:

输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。

输出描述:

可能有多组测试数据,对于每组数据,
将n个整数建立升序链表,之后遍历链表并输出。

#include<stdio.h>
#include<stdlib.h>
struct Node{
    int key;
    struct Node *next;
};
typedef struct Node linknode,*linklist;

void createlist(linklist L,int n){
    int i;int data;
    linklist p;linklist q;
    for(i=0;i<n;i++){
        scanf("%d",&data);
        q=L;
        p=(linklist)malloc(sizeof(linknode));
        p->key=data;
        p->next=NULL;
        /*
        q->next=p;
        q=p;*/
        while(data>q->next->key&&q->next!=NULL){ //令q为头结点,每次依次判断q的next节点,即从链表的首节点开始判断,若data比下一个节点要大,则寻找下一个节点
            q=q->next;                           //直到data比下一个节点要小,就开始插入,之所以比较下一个节点的值是为了保证插入时知道插在哪个节点后。
        }
        p->next=q->next;
        q->next=p;
        
    }
}


void order(linklist L){   //遍历一遍链表
    printf("%d",L->key);
    if(L->next!=NULL){
        printf(" ");
        order(L->next);
    }
}

int main(){
    int n;linklist L;
    while(scanf("%d",&n)!=EOF){
        L=(linklist)malloc(sizeof(linknode));//设立了头节点,使得第一个节点不用特殊讨论
        L->next=NULL;
        createlist(L,n);
        order(L->next);
    }
    return 0

守形数

题目描述

守形数是这样一种整数,它的平方的低位部分等于它本身。 比如25的平方是625,低位部分是25,因此25是一个守形数。 编一个程序,判断N是否为守形数。

输入描述:

输入包括1个整数N,2<=N<100。

输出描述:

可能有多组测试数据,对于每组数据,
输出"Yes!”表示N是守形数。
输出"No!”表示N不是守形数。
#include<stdio.h>

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int square = n*n;
        int sub=10;
        while(square%sub!=n){  //不断扩大sub位,求余数,如果是守形数,当sub位数与平方数位数相同时余数一定等于n
            if(square%sub==square){//
                printf("No!\n");
                return 0;
            }
            sub=sub*10;//10->100->1000->10000...
        }
        printf("Yes!\n");
    }
    return 0;
}

矩阵最大值

题目描述

编写一个程序输入一个mXn的矩阵存储并输出,并且求出每行的最大值和每行的总和。 要求把每行总和放入每行最大值的位置,如果有多个最大值,取下标值最小的那一个作为最大值。 最后将结果矩阵输出。

输入描述:

输入的第一行包括两个整数m和n(1<=m,n<=100),分别代表矩阵的行和列的维数。
接下来的m行每行有n个数,代表矩阵的元素。

输出描述:

可能有多组测试数据,对于每组数据,输出按题目要求执行后的矩阵。
#include<stdio.h>

int main(){
    int i;
    int j;
    int sum=0;
    int max;
    int mtmp;
    int row;int col;int data[100][100];
    while(scanf("%d%d",&row,&col)!=EOF){
        for(i=0;i<row;i++){
            for(j=0;j<col;j++){
                scanf("%d",&data[i][j]);    //
            }
        }
        for(i=0;i<row;i++){                    //每行依次求和、求最大值
            max=data[i][0];
            mtmp=0;
            sum=0;
            for(j=0;j<col;j++){
                sum=sum+data[i][j];            //求和
                if(data[i][j]>max){            //相同的最大值不替换
                    max=data[i][j];
                    mtmp=j;                    //记录最大值标号j
                }
            }
            data[i][mtmp]=sum;                 //存此行的和到最大值所在列
        }
        
        for(i=0;i<row;i++){
            for(j=0;j<col;j++){
                printf("%d",data[i][j]);
                if(j!=col-1){
                    printf(" ");
                }
            }
            printf("\n");
        }
    }
    
    return 0;
}



最小年龄的3个职工

题目描述

职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来。

输入描述:

输入第一行包括1个整数N,1<=N<=30,代表输入数据的个数。
接下来的N行有N个职工的信息:
包括职工号(整数), 姓名(字符串,长度不超过10), 年龄(1<=age<=100)。

输出描述:

可能有多组测试数据,对于每组数据,
输出结果行数为N和3的较小值,分别为年龄最小的职工的信息。
关键字顺序:年龄>工号>姓名,从小到大。
#include<stdio.h>
#include<stdlib.h>

struct staffnode{
    int id;
    char name[10];
    int age;
};
typedef struct staffnode staff,*ssss;

int cmp(const void *s1,const void *s2){ //qsort函数的cmp写法
    if((*(ssss)s1).age!=(*(ssss)s2).age){
        return (*(ssss)s1).age>(*(ssss)s2).age;//前面比后面大,则返回true,qsort排序结果是由小到达(0->n)
    }
    return (*(ssss)s1).id>(*(ssss)s2).id;
}

int main(){
    int n;
    staff s[31];
    int i;int j;
    while(scanf("%d",&n)!=EOF){
        for(i=0;i<n;i++){
            scanf("%d%s%d",&s[i].id,&s[i].name,&s[i].age);
        }
        
        qsort(s,n,sizeof(s[0]),cmp);          //调用c的qsort排序,第一个参数为数组地址,第二个参数为数组元素个数,第三个参数为数组元素大小,第四个为比较函数
        
        for(j=0;j<3;j++){
            printf("%d %s %d\n",s[j].id,s[j].name,s[j].age);
        }
    }
    return 0;
}



对称矩阵

题目描述

输入一个N维矩阵,判断是否对称。

输入描述:

输入第一行包括一个数:N(1<=N<=100),表示矩阵的维数。
接下来的N行,每行包括N个数,表示N*N矩阵的元素。

输出描述:

可能有多组测试数据,对于每组数据,
输出"Yes!”表示矩阵为对称矩阵。
输出"No!”表示矩阵不是对称矩阵。

#include<stdio.h>

int main(){
    int n;
    int i;int j;
    int matrix[100][100];
    while(scanf("%d",&n)!=EOF){
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                scanf("%d",&matrix[i][j]);
            }
        }
        for(i=0;i<n;i++){
            for(j=i;j<n;j++){
                if(matrix[i][j]!=matrix[j][i]){
                    printf("No!\n");
                    return 0;
                }
            }
        }
        printf("Yes!\n");
    }
    return 0;
}




 
  

打印日期

题目描述

给出年分m和一年中的第n天,算出第n天是几月几号。

输入描述:

 
  

输入包括两个整数y(1<=y<=3000),n(1<=n<=366)。

输出描述:

 
  

可能有多组测试数据,对于每组数据,按 yyyy-mm-dd的格式将输入中对应的日期打印出来。

#include<stdio.h>
int main(){
    int m;
    int n;
    int yearday;
    int i;
    int month[2][13]={{0,31,29,31,30,31,30,31,31,30,31,30,31},{0,31,28,31,30,31,30,31,31,30,31,30,31}};
    int flag=0;
    while(scanf("%d%d",&m,&n)!=EOF){
        if((m%100!=0&&m%4==0)||(m%400==0)){
            yearday=366;
            flag=0;
        }else{
            yearday=365;
            flag=1;
        }
        
        if(yearday==365&&n==366){printf("输入有错误!!");return 0;}
        int k=n;i=1;
        while(k>month[flag][i]){
            k=k-month[flag][i];
            i++;
        }
        if(k>0&&k<=month[flag][i]){
            printf("%d-%02d-%02d\n",m,i,k);
        }
    }
    return 0;
}



大整数排序

题目描述

对N个长度最长可达到1000的数进行排序。

输入描述:

输入第一行为一个整数N,(1<=N<=100)。
接下来的N行每行有一个数,数的长度范围为1<=len<=1000。
每个数都是一个正数,并且保证不包含前缀零。

输出描述:

可能有多组测试数据,对于每组数据,将给出的N个数从小到大进行排序,输出排序后的结果,每个数占一行。

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

struct node{
    int len;
    char key[1000];
};

typedef struct node Num;
int cmp(const void *s1,const void *s2){
    int i;
    if((*(Num *)s1).len!=(*(Num *)s2).len){
        return (*(Num *)s1).len>(*(Num *)s2).len;   //优先判断长度
    }
    if((*(Num *)s1).len==(*(Num *)s2).len){
        int L=(*(Num *)s1).len;
        for(i=0;i<L;i++){
            if((*(Num *)s1).key[i]!=(*(Num *)s2).key[i]){
                return (*(Num *)s1).key[i]>(*(Num *)s2).key[i];      //长度相等判断每一位
            }
        }
    }
    return 0;
}
int main(){
    int n;
    Num data[100];
    int len[100];
    int i;
    while(scanf("%d",&n)!=EOF){
        for(i=0;i<n;i++){
            scanf("%s",data[i].key);
            data[i].len=strlen(data[i].key);
        }
        qsort(data,n,sizeof(data[0]),cmp);
        for(i=0;i<n;i++){
            printf("%s\n",data[i].key);
        }
        
    }
    return 0;
}



N阶楼梯上楼

题目描述

N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式。(要求采用非递归)

输入描述:

输入包括一个整数N,(1<=N<90)。

输出描述:

可能有多组测试数据,对于每组数据,
输出当楼梯阶数是N时的上楼方式个数。

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

int F(int n){
    if(n<0){return 0;}
    if(n==0){return 1;}
    int count1=F(n-1);
    int count2=F(n-2);
    return count1+count2;
}
int main(){
    int n;int i;
    int a[90];
    while(scanf("%d",&n)!=EOF){
        a[1]=1;
        a[2]=2;
        for(i=3;i<=n;i++){
            a[i]=a[i-1]+a[i-2];
        }
        printf("%d",a[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/y649014081/article/details/79317550