以下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;
}