oj平台1206

从昨晚老师布置到现在,终于做完了这几道题,感觉每一道都不简单,所以留个记录:

题目一:

小南现在有一段由小写字母组成的文本s,他每天的工作就是找到文本中两个相邻并且相同的字母,然后删除它们。注意这个删除过程可能是重复的,比如:
"abbac"->"aac"->"c"。 也就是说最终的文本中没有相邻相同的字母。

 输入:单样例。每个测试文件只有一个样例输入,输入的一行文本的长度len满足1≤len≤105。

输出:输出一行,代表处理后的文本。

样例输入:abbbac

样例输出:abac

代码:

#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main()
{
	char* a;
	a = (char*)malloc(sizeof(char) * 100000);//100000太大了,可以用动态分配
//(其实是自己设这么大的字符串,系统给报错,查了一下只能用动态分配,希望以后可以知道为什么)
	scanf("%s", a);
	int len = strlen(a);
	a[len] = 0;
	int i, j;
	int flag = 1;
	while (flag == 1)//只要发生了消除,循环就继续,知道历遍之后没有消除,跳出循环
	{
		flag = 0;
		for (i = 0;i < len - 1;i++)
		{
			if (a[i] == a[i + 1])
			{
				for (j = i + 2;j < len;j++)//自己最开始设j=i,发现会导致超限的问题
				{
					a[j - 2] = a[j];
				}
				len = len - 2;
				a[len] = 0;
				flag = 1;
			}
		}
	}
	printf("%s", a);
}

这道题比较简单,主要问题出在动态分配和j的初始化上。

题目二:

小南现在有两个字符串S1和S2,他定义了一种字符串减法,S1-S2即在S1中去除掉所有S2中的字符所剩下的字符串。
举例: S1="ABA", S2="A",则 S1-S2="B"。

输入

输入包含多组测试用例。每组测试用例包括两个字符串S1和S2,字符串长度不超过104。每个字符串都是由可见ASCII字符和空格组成。

输出

对于每组测试用例,输出S1-S2的结果。每个输出占一行。

样例输入

ABA
A
A B&&1
&

样例输出 Copy

B
A B1

提示

对于输入包含空格的字符串时,最好采用while(gets(a)!=NULL)处理多样例。

代码:

#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main()
{
	char* a = (char*)malloc(sizeof(char) * 10000);
	char* b = (char*)malloc(sizeof(char) * 10000);
//鉴于上个题,这个题我直接cv的动态分配
	int c[128];//ASCII码共127
	while ((gets(a)) != NULL)//对于输入包含空格的字符串时,最好采用while(gets(a)!=NULL)处理多样例。
	{
		gets(b);
		int i=0;
		char m;
		for (i = 0;a[i]!='\0';i++)
		{
			c[a[i]] = 1;//对于a中出现的ASCII码标记为1;
		}
		for (i = 0;b[i] != '\0';i++)
		{
			c[b[i]] = 0;//对于b中的ASCII码标记为0;
		}
		for (i = 0;a[i] != '\0'; i++)
		{
			if (c[a[i]] == 1)//如果a中的ASCII码为1,则输出
			{
				printf("%c", a[i]);
			}
		}
		printf("\n");
	}
}

对于这个题真的太值得我说了,交了好多次时间超限,也不是算法的问题,是思维的问题。

最开始,我是选择用a中的字符一个一个与b中的字符比较,如果一样,就让a的字符往前移一位,消去那个相同的字符,类似于第一题,是的,显而易见,他超限了。

然后我就想着改进,我首先对b数组下手,对于b中所有重复的字符进行删除,减少b的长度,在进行历遍比较,依然超限。

紧接着,去求助了朋友,对于出现过的ASCII码进行标记。

于是出现了我的第三版和第四版的错误。

第三版,鉴于懒惰,删去了b数组,而是选择用m=getchar();类似于:

while ((gets(a)) != NULL)
{
	int i = 0;
	while (1)
	{
		m = getchar();
		if (m == '\n')
			break;
		else
		{
			c[m] = 0;
		}
	}
}

但是很快出现了问题,就是不会删去b中的字符,调试之后发现,是根本没有进while循环,我猛然想起getchar的范围是很广泛的,它很有可能把gets的那个回车吃了。所以我再次改代码,出现了第四版的错误:

while ((gets(a)) != NULL)
{
	int i = 0;
	while (1)
	{
		m = getchar();
		if (m == '\n'&& i != 0)
			break;
		else
		{
			c[m] = 0;
			i = 1;
		}
	}
}

但是这个交过去,超限了,我思考了一下,问题可能是while(1)导致的,但是也不直到具体是什么,可能是b可能为空?(不清楚)反正我最后放弃了get,选择了gets(不过是再历遍一次)。所以出现了我的最终代码。

而且从这个题我可以收获两点:

首先,对于有空格的字符串,用gets,因为scanf读取字符串会选择回车键和空格作为结尾,而gets仅用回车键作为结尾,除此以外,while((get(a))!=NULL)也是个新鲜的。

其次,是不必去求出字符串长度,在for中对于字符串的历遍,可以用a[i]!='\0'作为条件。

第三题:

小南跟着导师进行科研调查,得到了n个自然数(1≤n≤200000),每个数均不超过1500000000(1.5*109),即long型。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。你能帮他编程实现吗? 

输入

单样例。每个测试文件只包含一组测试数据:
第一行是整数n,表示自然数的个数;
第2~n+1行,每行一个自然数。

输出

输出包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

样例输入 Copy

8
2
4
2
4
5
100
2
100

样例输出 Copy

2 3
4 2
5 1
100 2

提示

也可以用结构体处理。

代码:

#include <stdio.h>
#include <string.h>
long long  a[200001];
long long  PartSort(long long * a, long long  left, long long  right);
void QuickSort(long long * a, long long  left, long long  right);
int main()
{
	long long  n,i,j;
	scanf("%ld", &n);
	for (i = 0;i < n;i++)
	{
		scanf("%ld",&a[i]);
	}
	QuickSort(a, 0, n - 1);//快排 先将他们排好顺序,然后进行统计
	long long  t = 1;
	for(i=0;i<n;i++)
	{
		if (a[i] == a[i + 1])
		{
			t++;
		}
		else
		{
			printf("%d %d\n", a[i], t);
			t = 1;
		}
	}
}
long long  PartSort(long long * a, long long  left, long long  right)
{
	long long  pivot = a[left];
	while (left != right)
	{
		while (left < right && a[right] >= pivot)
			right--;
		a[left] = a[right];
		while (left < right && a[left] <= pivot)
			left++;
		a[right] = a[left];
	}
	a[left] = pivot;

	return left;
}

void QuickSort(long long * a, long long  left, long long  right)
{
	long long  mid = 0;


	if (left < right)
	{
		mid = PartSort(a, left, right);
		QuickSort(a, left, mid - 1);
		QuickSort(a, mid + 1, right);
	}

	return;
}

对于这道题,提示说可以用结构体哈,所以我很认真的用链表写了一遍,写的很好,没啥问题,就是超限了(哭)

然后就上网搜嘛(菜,没办法),然后得知了可以先进行排序,然后统计。

这个方法好呀,然后就诞生了我第二个超限的代码,我用的是冒泡排序。

最后,改为快排,成功提交。最后我才知道可以用结构体是对于我代码中的那个t来说,不过这样写和结构体都差不多,只是这样不要忘了t初始化。

对于快排,后来才知道C语言里有这个函数。
qsort是C语言中的快排函数,包含在<stdlib.h>中,函数一共有四个参数,没有返回值。

int (*cmp)(const void *,const void *);

qsort(*s, n, sizeof(s[0]), cmp);

 s是参与排序的首地址,n为需要排序的数量,sizeof(s[0])是每一个元素占用的空间大小,cmp是排列的顺序。

qsort(a, 1000, sizeof(int), cmp);
其中cmp函数应写为:
int cmp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b; //由小到大排序
    //return *(int *)b - *(int *)a; 由大到小排序
}

cam的返回值大于等于0不进行置换,小于0进行置换。
原文链接:https://blog.csdn.net/f_zyj/article/details/51484751

 

第四题:

两个多项式相加:相应指数的系数相加。例如当A为3X4-6X2+5X-10,B为1X4+6X3+5,则A+B的结果为4X4+6X3-6X2+5X-5。
说明:此题可以用循环或结构体或链表完成。

输入

单样例。样例的第一行输入包含两个整数m,n,分别表示多项式A的项数和多项式B的项数。
接下来的m行,每行包含两个用空格分开的整数a和b,代表多项式A的m项的系数和指数。
再接下来的n行,每行包含两个用空格分开的整数a和b,代表多项式B的n项的系数和指数。

输出

输出两个多项式相加的结果。输出格式为:从较高指数到较低指数,依次输出相加后多项式的系数和指数,每项输出一行。注意系数为0的项也不输出。

样例输入 Copy

2 3
1 2
1 1
2 2
1 1
2 0

样例输出 Copy

3 2
2 1
2 0

提示

也可以用链表来实现:一条单链表可以表示一个一元多项式,每个节点包含三个域:指数、系数和后继节点的指针。

代码:

#include <stdio.h>
#include <stdlib.h>
struct note {
	int xi;
	int zhi;
	struct note* next;
};//使用链表
int main()
{
	
	struct note* cur, * pre, * new_code;//照搬书上,自己写总出错(悲)
	int m, n;
	while ((scanf("%d %d", &m, &n)) != EOF)
	{
		struct note* head = NULL;
		int i;
		for (i = 0;i < m;i++)
		{
			new_code = malloc(sizeof(struct note));
			scanf("%d %d", &new_code->xi, &new_code->zhi);
			for (cur = head, pre = NULL;cur != NULL && new_code->zhi < cur->zhi;pre = cur, cur = cur->next);//先创造一个链条,书上看懂的话这个很好理解
			new_code->next = cur;
			if (pre == NULL)
				head = new_code;
			else
				pre->next = new_code;
		}
		for (i = 0;i < n;i++)
		{
			new_code = malloc(sizeof(struct note));
			scanf("%d %d", &new_code->xi, &new_code->zhi);
			for (cur = head, pre = NULL;cur != NULL && new_code->zhi < cur->zhi;pre = cur, cur = cur->next);
			if (cur != NULL && new_code->zhi == cur->zhi)//如果相等,系数相加
			{
				cur->xi = cur->xi + new_code->xi;
			}
			else //如果未找到这个系数,就把它加到链表上
			{
				new_code->next = cur;
				if (pre == NULL)
					head = new_code;
				else
					pre->next = new_code;
			}
		}
		struct note* p;
		for (p = head;p != NULL;p = p->next)//打印
		{
			if(p->xi!=0)
			printf("%d %d\n", p->xi, p->zhi);
		}
		
	}

这个其实没啥好说的,只是用到了链表。

题目五:

输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。
你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。

输入

每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。  
输入数据保证:分割得到的非负整数不会大于100000000,输入数据不可能全由‘5’组成。

输出

输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。

样例输入 Copy

0051231232050775

样例输出 Copy

0 77 12312320

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int cmp(const void* a, const void* b);//快排
int main()
{
	char str[1000] ;
	while (scanf("%s", str) != EOF) {
		int len = strlen(str);
		int a[1000];
		int n = 0, i = 0;
		while (i < len) {
			int k = 0;//标记位数
			while (str[i] == '5' && i < len) {
				i++;
			}
			while (str[i] != '5' && i < len) {
				k++;i++;
			}
			if (k) {
				int num = 0;
				while (k--) {
					num = num * 10 + (str[i - k - 1] - '0');
				}
				a[n++] = num;
			}
		}
		qsort(a, n, sizeof(int), cmp);//快排
		for (i = 0;i < n;i++)printf("%d ", a[i]);
		putchar('\n');
	}
	return 0;
}
int cmp(const void* a, const void* b) {
	return (*(int*)a - *(int*)b);
}

(其实这个是cv朋友的代码)

怎么说呢,其实很好看懂,就是把它转化为数字很难搞,还有就是,有可能5不一定在结尾,所以我最初的想法,检索到5后返回,是不可取的。

在这里加几个函数,可以将字符串转化为数字:

#include <stdlib.h>

函数:

atoi:可以把字符串转为int

atol:可以把字符串转为long

atof:可以把字符串转为double

/*
 * 程序名:book.c,此程序用于演示atoi函数族。
 * 作者:C语言技术网(www.freecplus.net) 日期:20190525。
*/
int main()
{
  int ii=0;
  ii=atoi("123");
  printf("ii=%d\n",ii);  // 输出ii=123

  ii=atoi("123abc");
  printf("ii=%d\n",ii);  // 输出ii=123,合法数字后的abc被忽略。

  ii=atoi("abc123");
  printf("ii=%d\n",ii);  // 输出ii=0,数字前有字符为非法。

  ii=atoi("+123");
  printf("ii=%d\n",ii);  // 输出ii=123,+是合法字符。

  ii=atoi("-123");
  printf("ii=%d\n",ii);  // 输出ii=-123,-是合法字符。
}

第六题:

对给定的正整数n,找到比n大的最小的那个回文数p。由于n(0 <n< 1010000)可能是一个很大的数,所以只能用字符串来处理。你能帮他编写一个程序实现吗?

输入

多组样例。每组样例输入一个正整数n(0 <n< 1010000),并且n不会有前导0。

输出

对于每组输入,输出比n大的最小的那个回文数p。每个结果占一行。

样例输入 Copy

44
3
175
9
99
1331
19991

样例输出 Copy

55
4
181
11
101
1441
20002
//版权声明:本文为CSDN博主「龙阳*」的原创文章,
//原文链接:https://blog.csdn.net/qq_59125846/article/details/123960621
# include<stdio.h>
# include<string.h>
int main(){
    char a[10005];
    while(~scanf("%s",a))
    {
        int len=strlen(a);
        int flag=0;
        for(int i=len/2-1;i>=0;i--)
        {
        if(a[i]>a[len-i-1])
        {
        flag=1; 
        break;  
        }   
        else if(a[i]<a[len-i-1]) 
            {
                flag=0;
                break;
            }
        }       
        if(!flag)
        {
            for(int i=(len-1)/2;i>=0;i--)
            {
                a[i]++;
                if(a[i]>'9')
                a[i]='0';
                else break;
            }
            if(a[0]=='0')
            {
                a[0]='1';
                len++;
                a[len/2]='0';
            }                       
        }
        for(int i=0;i<len/2;i++)
        printf("%c",a[i]);
        for(int i=(len+1)/2-1;i>=0;i--)
        printf("%c",a[i]);
        printf("\n");
    }
     
    return 0;
}

是的,这个代码是我直接上网搜的,这个只是稍微理解了一点点。

第七题:

火车从始发站(称为第1站)开出,在始发站上车的人数为w,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,都是t,因此在第2站开出时(即在到达第3站之前)车上的人数保持为w人。从第3站起(包括第3站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n-1站),都满足此规律。现给出的条件是:共有n个车站(1≤n≤100),始发站上车的人数为w,最后一站下车的人数是m(全部下车)。需要求解x站开出时车上的人数是多少。

输入

单样例。每个测试文件只包含一组测试数据,输入的一行包括四个整数w、n、m和x(均不超过int数据类型,其中1≤n≤100)。

输出

对于输入的一组测试数据,输出一个整数,代表从x站开出时车上的人数。

样例输入 Copy

5 7 32 4

样例输出 Copy

13

代码:

#include <stdio.h>
int main()
{
	int w, n, m, x, t, i;
	scanf("%d %d %d %d", &w, &n, &m, &x);
	int a[100];
	a[0] = w;
	a[1] = 0;
	for (i = 2;i < n;i++)
	{
		a[i] = a[i - 1] + a[i - 2];//计算增加总人数中和w有关的
//其实,从第三站开始,所车上所增加的人数为前两站上车的人数
	}
	int sum = w;
	for (i = 0;i < (n - 3);i++)
	{
		sum = sum + a[i];//计算总人数,注意此时i<n-3
	}
	int b[100];
	b[0] = 0;
	b[1] = 1;
	for (i = 2;i < n;i++)
	{
		b[i] = b[i - 1] + b[i - 2];
	}
	int sumb;
	sumb = 0;
	for (i = 0;i < (n - 3);i++)
	{
		sumb = sumb + b[i];//计算增加总人数中t的个数
	}
	t = (m - sum) / sumb;//m其实是最终的人数,从而得出t的数量
	a[1] = t;//然后将a[1]赋值为t,然后进行计算就好了
	for (i = 2;i < x;i++)
	{
		a[i] = a[i - 1] + a[i - 2];
	}
	sum = w;
	for (i = 0;i < x - 2;i++)
	{
		sum = sum + a[i];
	}
	printf("%d\n", sum);
}

 这个题之前做过,当时就算了很久,不是程序的问题,是自己算不明白。

题目八:

字符反码的定义:对于字符x和它的反码y之间满足如下关系:
(1)如果x是小写字母字符,则x和字符'a’的距离等于它的反码y和字符'z’ 的距离;
(2)如果x是大写字母字符,则x和字符'A’的距离等于它的反码y和字符'Z’的距离;
(3)如果x不是小写字母也不是大写字母,它的反码y等于x。
例如:'a’的反码是'z’;'c’的反码是'x’;'W’的反码是'D’;'1’的反码还是'1’;'$'的反码还是'$'。
一个字符串的反码定义为其所有字符的反码,你的任务就是计算出给定字符串的反码。

输入

输入每行都是一个字符串,字符串长度不超过 80 个字符。

输出

对于输入的每个字符串,输出其反码。

样例输入 Copy

Hello 

样例输出 Copy

Svool 

代码:

#include <stdio.h>
#include <string.h>
int main()
{
	int n, i;
	char a[81];
	while ((gets(a)) != NULL)
	{
		int len = strlen(a);
		for (i = 0;i < len;i++)
		{
			if (a[i] >= 65 && a[i] <= 90)
			{
				a[i] = 90 - (a[i] - 65);
			}
			else if (a[i] >= 97 && a[i] <= 122)
			{
				a[i] = 122 - (a[i] - 97);
			}
		}
		puts(a);
	}
}

 这道题挺简单的,没啥好说的。

题目九:

如果一个整数只能被1和自己整除,就称这个数是素数。 ps: 1不是素数。
如果一个数正着反着都是一样,就称为这个数是回文数。例如:6, 66, 606, 6666
如果一个数字既是素数也是回文数,就称这个数是回文素数 。
老师现在给小南一个任务,让他求出给定的区间[L, R](包括边界L和R)内有多少个回文素数。你能帮助他吗?

输入

多组测试用例。每组测试用例输入一行,包含两个正整数L和R(1≤L≤R≤1000)。

输出

对于每个测试样例,输出一个整数,代表 [L,R] 内回文素数的数量。每个结果占一行。

样例输入 Copy

1 10
100 120

样例输出 Copy

4
1
#include <stdio.h>
#include <math.h>
int main()
{
	int L,R,i,I;
	int judge1=1,judge2=1;
	while ((scanf("%d %d",&L,&R))!=EOF)
	{
		int r;
	    int sum=0;
		for(I=L;I<=R;I++)
		{
			judge1=1,judge2=1;
			r=sqrt((double)I);
			int j;
			if(I==1)
			{
				judge1=0;
			}
			if(I>=4)
			{
				for(j=2;j<=r;j++)
			{
				if(I%j==0)
				{
					judge1=0;
					break;
				}
			}
			}
			int a[4],b[4];
			int digit=0;
			for(i=0;i<4;i++)
			{
				a[i]=b[i]=10;
			}
			if(I<10)
			{
				if(judge1==1)
				{
					sum++;
				}
			}
			else
			{
				int l=I;
			for(i=0;l>0;l=l/10)
			{
				a[i]=b[i]=(l%10);
				digit++;
				i++;
			}
			for(i=0;i<digit;i++)
			{
				if(a[i]!=b[digit-1-i])
				{
					judge2=0;
				}
			}
			if((judge1==1)&&(judge2==1))
			{
				sum++;
			}
			}
		}
		printf("%d\n",sum);
	}
}

 这是很久之前写的,直接cv交的,当时写的不怎么好,有点长,但是总归是历遍,没什么难度。

题目十

输入一个整数n,求它后一个素数和前一个素数的差值。输入是素数时输出0。n不超过1299709(第100000个素数)。例如,n=27时输出29-23=6。
 

输入

单样例,每次输入一个整数n。

输出

输出满足条件的素数之间的差值,如果输入的整数是素数,则输出0。

样例输入 Copy

27

样例输出 Copy

6

代码:

#include <stdio.h>
#include <math.h>
int prime(int p);
int main()
{
	int i, k, n;
	scanf("%d", &n);
		if (prime(n) == 1)
		{
			printf("0");
		}
		else
		{
			for (i = n - 1;;i--)
			{
				if (prime(i) == 1)
					break;
			}
			for (k = n + 1;;k++)
			{
				if (prime(k) == 1)
					break;
			}
			printf("%d", k - i);
		}
}
int prime(int p)
{
	int i, flag = 1;
	if (p <= 1)
		return 0;
	if (p == 2)
		return 1;
	if (p == 3)
		return 1;
	else
	{
		int q;
		q = (int)sqrt((double)p);
		for (i = 2; i <= q; i++)
		{
			if (p % i == 0)
			{
				flag = 0;
				break;
			}
		}
		return flag;
	}
}

还是哈,没啥好说的,依旧可以用历遍。

其实如果最大的素数范围可以小一点,完全可以编写程序把他们打印出来然后放入一个数组里,那是最快的。

题目十一:

现在知道假币的重量比真币的质量要轻。现在有一个天平,我们知道从n个硬币中找出假币的方法有很多种,最简单的就是两两称重穷举的方法,称重n/2次就可以找出来。但是老师希望小南用最快的速度也就是最少的称重次数把那个假币找出来,你能帮他算算最少的称重次数是多少吗? 

输入

多样例。每个样例输入一行,包括一个正整数n(1≤n≤230),表示硬币的数目。当输入的n为0时,结束样例输入。 

输出

每个测试样例输出一个正整数,表示最少的称重次数。 

样例输入 Copy

3
12
0

样例输出 Copy

1
3

提示

假设有3枚硬币,可以任意取2个放天平上称量一下。 
因为假币的重量比较轻。 
如果天平不平衡,则较轻的那枚就是假币。 
如果天平平衡,则说明这两枚硬币都是真的,而剩下那枚是假币。
所以3枚硬币的最少称重次数是1次,那么4枚呢?5枚呢?可以找出硬币数与称重次数之间的关系。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int n = 0;

	while (1)
	{
		scanf("%d", &n);
		int flag = 0;
		if (n == 0)
			break;
		else if (n == 1) 
		{
			printf("0\n");
		}
		else
		{
			long long num = 1;
			while (num < n) {
				flag++;
				num = 3 * num;
			}
			printf("%d\n", flag);
		}
	}
	return 0;
}

 这道题啊,看这个网站吧https://www.offcn.com/sydw/2017/0920/319468.html

总结来说:当问称量几次可以找到假币:3^>x;当问及判断假币和真币谁重,仅用两次。

题目十三:

我没有记错顺序,只是做完十二题的代码稍微改改就交十三了,所以把十三的放在这十二只讲思路。

老师给了小南一些日期,日期格式为:MM/DD/YYYY。要求小南编程将其按日期大小排列,你能帮他完成吗?
输入

单样例。输入的第一行是一个整数n(0<n<100),表示要排序日期的个数。
接下来的n行,每行输入一个日期,格式为MM/DD/YYYY。

输出

从小到大输出排序后的日期。

样例输入 Copy

3
02/21/2003
11/12/1999
10/22/2003

样例输出 Copy

11/12/1999
02/21/2003
10/22/2003

提示

也可以用链表实现。

代码:

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

int main()
{
	int n;
	while ((scanf("%d", &n)) != EOF)
	{
		struct part
		{
			int M;
			int D;
			int Y;
		}group[101];
		int i,j;
		for (i = 0;i < n;i++)
		{
			scanf("%d/%d/%d", &group[i].M,&group[i].D,&group[i].Y);
		}
		struct part tem;
		for (i = 0; i < n - 1; i++)
		{
			int count = 0;
			for (j = 0; j < n - 1 - i; j++)
			{
				if (group[j].Y > group[j+1].Y)
				{
					tem = group[j];
					group[j] = group[j+1];
					group[j+1] = tem;
					count = 1;

				}
				else if(group[j].Y == group[j + 1].Y)
				{
					if (group[j].M > group[j + 1].M)
					{
						tem = group[j];
						group[j] = group[j + 1];
						group[j + 1] = tem;
						count = 1;

					}
					else if(group[j].M == group[j + 1].M)
					{
						if (group[j].D > group[j + 1].D)
						{
							tem = group[j];
							group[j] = group[j + 1];
							group[j + 1] = tem;
							count = 1;

						}
					}
				}
			}
			if (count == 0)
				break;
		}
		for (i = 0;i < n;i++)
		{
			printf("%02d/%02d/%d\n", group[i].M,group[i].D,group[i].Y);
		}
	}
}

没有用链表,只用了结构体,用链表写大概和第四题那个差不多,只是抛去了相等时候的处理环节和多加几层内部结构,毕竟需要多次比较。

只是用到了结构,毕竟刚学结构,还感觉很新鲜。

问就是我喜欢冒泡,毕竟用习惯了,如上面所说,内部结构比较多,判断比较多。

题目十二:

小南有n个整数,这些整数都非常大,所以没有办法采用整数排序的方法处理,请聪明的你帮小南编写程序完成这些整数由小到大的排序。

输入

输入包含多组测试用例。
对于每一组测试用例,第一行包含一个整数n(0<n≤200)。 
接下来n行每行包含一个整数x  (0≤x≤101000)。

输出

对于每一组测试数据,输出排序后的结果。

样例输入 Copy

2
20
10
3
11111111111111111111111111111
22222222222222
33333333

样例输出 Copy

10
20
33333333
22222222222222
11111111111111111111111111111

所以现在再看十二题,同样用结构体,当然也可以用链表,链表依然参照第四题,仅用结构体参照十三题。需要判断两个条件,首先用判断长度进行排序,长度相同再利用strcmp函数比较两个字符串即可。结构体里放两个内容,一是读取的字符串,二是字符串的长度,如果有指针再加上指针。

 

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值