写了5题才通过了3个,那两个实在不知道怎么回事了?。菜的一笔。
前几个感觉没什么好记录的点,虽然1003还没完全对。后面两个题还是可以记一下
- 1004
最近遇到好几个题目都和这个方面有点关联。先是考研的专业课里面,出了一个编程题。说有一个学生信息的结构体,姓名、学号都是字符串存储,然后要将n个学生的信息按照姓名的字典顺序冒泡排序,我一开始想这还不简单。稍微想了一下就开始往试卷上写,写到冒泡的交换的部分时,突然发现这里有个坑。字符数组不能像其他基本类型一样直接赋值,得用strcpy将里面元素逐个拷贝。当时还想牛逼啊,还好看出来了?。考完上实习课的时候,是写一个通讯录,里面的人名等也是用字符串存储,不过老师用的字符指针,存储的时候再申请内存。孤陋寡闻了,第一次看到这样写,貌似这个比我那个写法要高明一些,这下就可以不用考虑那个字符数组深拷贝问题了,可以结构体整体赋值。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student{
char *name;
char *id;
int score;
}student;
int main()
{
student *stu;
student *max,*min;
int n;
int i = 0;
scanf("%d",&n);
stu = (student *)malloc(sizeof(student) * n);
while(n--)
{
stu[i].name = (char *)malloc(sizeof(char) * 10);
stu[i].id = (char *)malloc(sizeof(char) * 10);
scanf("%s%s%d",stu[i].name,stu[i].id,&stu[i].score);
if(i == 0)
{
max = stu;
min = stu;
}
else
{
if(stu[i].score > max->score)
{
max = stu + i;
}
else
{
if(stu[i].score < min->score)
{
min = stu + i;
}
}
}
i ++;
}
printf("%s %s\n%s %s\n",max->name,max->id,min->name,min->id);
return 0;
}
- 1005
这里用的是类似hash表的意思,不过还有错误,等改出来再写上?。
刚刚看了同学的帖子,恍然大悟?。在此贴上链接https://blog.youkuaiyun.com/qq_36834256/article/details/802325671005. 继续(3n+1)猜想 (25)(可以多多关注欧?)
我的想法是用两个hash表,一个h[101]用来记录n在计算过程中出现的值,出现了就置1(初始为0),一个result[101]用来记录最后留下的值,每个n来到的时候都将result[n]和h[n]都置1,如果后面的计算过程中h[n]==0,在将h[n] =1,否的话,就将result[n] = 0(从结果中去除)。(这里内存占用就比较多了,再想想看怎么改进一下)。
我的错误在于当一个数为奇数的时候,下一个数就为(3*n+1)/2,所以就会出现下个值会大于100的情况,而我的哈希表是h[101],会造成越界。测试实例都是比较小的数,而且我后来测试的时候用的比较大的数都是偶数,就不会有越界的情况,答案也是对的,也就搞不懂到底哪里出错了。
改进的话,再算下一个数的时候,进行一下判断,如果大于100,就continue直接进行再下一个数的计算,不用参与到hash表的判断。
#include <stdio.h>
int main()
{
int k;
int n;
int h[101] = {0};
int i = 0;
int result[101] = {0};
int count = 0;
scanf("%d",&k);
for(i; i < k; i++)
{
scanf("%d",&n);
if(h[n] == 0)
{
result[n] = 1;
h[n] = 1;
count ++;
while(n != 1)
{
if(n % 2 == 0)
n = n - n / 2;
else
n = (3 * n + 1) / 2;
if(n > 100)//这里就是之后看出错误的地方
continue;
if(h[n] == 0)
h[n] = 1;
else
{
if(result[n])
{
result[n] = 0;
count --;
}
break;
}
}
}
}
for(i = 100;i;i--)
{
if(result[i])
{
printf("%d",i);
if(count != 1)
{
putchar(' ');
}
count --;
}
}
return 0;
}
改用链表存储结果的代码
#include <stdio.h>
#include <stdlib.h>
typedef struct res
{
int n;
struct res *next;
}res;
void insertLinkList(res *h,int n);
void deleteLinkList(res *h,int n);
int main()
{
int k;
int n;
int h[101] = {0};
int i = 0;
int result[101] = {0};
int count = 0;
res *l = NULL;
l = (res *)malloc(sizeof(res));
if(l == NULL)
{
printf("m内存错误\n");
return -1;
}
l->next = NULL;
scanf("%d",&k);
for(i; i < k; i++)
{
scanf("%d",&n);
if(h[n] == 0)
{
result[n] = 1;
h[n] = 1;
count ++;
insertLinkList(l,n);
while(n != 1)
{
if(n % 2 == 0)
n = n - n / 2;
else
n = (3 * n + 1) / 2;
if(n > 100)
continue;
if(h[n] == 0)
h[n] = 1;
else
{
deleteLinkList(l,n);
break;
}
}
}
}
res *p = l->next;
while(p != NULL)
{
printf("%d",p->n);
if(p->next)
putchar(' ');
p = p->next;
}
return 0;
}
void insertLinkList(res *h,int n)
{
res* t = (res*)malloc(sizeof(struct res));
if(t == NULL)
{
printf("内存错误\n");
return;
}
t->n = n;
res *pre = h;
res *p = pre->next;
while(p)
{
if(p->n < n)
break;
pre = pre->next;
p = p->next;
}
t->next = p;
pre->next = t;
}
void deleteLinkList(res *h,int n)
{
res *pre = h;
res *p = pre->next;
while(p)
{
if(p->n == n)
break;
pre = pre->next;
p = p->next;
}
if(p)
{
pre->next = p->next;
free(p);
}
}