C语言学习内容
###总结课本中数组部分的排序
#include<stdio.h>
int main()
{
int n,i,j,t,a[100];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
{
for(j=0;j<n-i;j++)
{
if(a[j]<a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
for(i=0;i<n;i++)
printf("%4d",a[i]);
return 0;
}
冒泡排序。
#include<stdio.h>
int main()
{
int n,i,j,t,a[100];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]<a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
for(i=0;i<n;i++)
printf("%4d",a[i]);
}
选择排序。
自行查找资料,学习了两种新的排序方法,插入排序和桶排序。
#include<stdio.h>
int main()
{
int n,i,j,array[100],temp;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&array[i]);
for(int i = 1;i<n;i++)
{
int temp = array[i];
for(j = i-1;j>=0;j--)
{
if(array[j]>temp)
{
array[j+1] = array[j];
}
else
{
break;
}
}
array[j+1] = temp;
}
for(i=0;i<n;i++)
printf("%5d",array[i]);
}
插入排序。
#include<stdio.h>
int main()
{
int n,i,j,t,tong[100];
for(i=0;i<100;i++)
tong[i]=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&t);
tong[t]++;
}
for(i=99;i>=0;i--)
for(j=0;j<tong[i];j++)
{
printf("%4d",i);
}
}
桶排序。
函数递归,理解汉诺塔问题,逆向思考问题。函数递归可以从结果反推。
#include<stdio.h>
void hanoi(int n,char x,char y,char z)
{
if(n==1)
{
printf("%c-->%c\n",x,z);
}
else
{
hanoi(n-1,x,z,y);
printf("%c-->%c\n",x,z);
hanoi(n-1,y,x,z);
}
}
int main()
{
int m;
scanf("%d",&m);
hanoi(m,'A','B','C');
}
汉诺塔问题。
杨辉三角,二维数组的的应用,引深学习多维数组。简单了解多维数组的定义,初始化。
#include<stdio.h>
int main()
{
int i,j,a[10][10],n;
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[i][0]=1;
a[i][i]=1;
}
for(i=0;i<n;i++)
{
for(j=1;j<i;j++)
{
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
for(j=0;j<=i;j++)
printf("%5d",a[i][j]);
printf("\n");
}
}
这也可以由一位数组完成,了解不同维数组之间的关系
#include<stdio.h>
#define N 6
int main()
{
int i,j,a[6]={1};
for(i=0;i<6;i++)
{
for(j=i;j>0;j--)
a[j]=a[j]+a[j-1];
for(j=0;j<=i;j++)
printf("%5d",a[j]);
printf("\n");
}
}
杨辉三角。(一维数组完成)
指针学习
1.指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:
(1)intptr;//指针的类型是int
(2)charptr;//指针的类型是char
(3)intptr;//指针的类型是int
(4)int(ptr)[3];//指针的类型是int()[3]
(5)int*(ptr)[4];//指针的类型是int(*)[4]
2.指针所指向的类型
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符去掉,剩下的就是指针所指向的类型。
例如:
(1)intptr; //指针所指向的类型是in
t(2)charptr; //指针所指向的的类型是char
(3)int**ptr; //指针所指向的的类型是int
(4)int(ptr)[3]; //指针所指向的的类型是int()[3]
(5)int(ptr)[4]; //指针所指向的的类型是int()[4]
在指针的算术运算中,指针所指向的类型有很大的作用。指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C 越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。
3.指针的值----或者叫指针所指向的内存区或地址
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32 位程序里,所有类型的指针的值都是一个32 位整数,因为32 位程序里内存地址全都是32 位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为si zeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX 为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。
刷题部分
查找资料,学习“三连击”问题。
首先这是网上查找的资料,
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[10], b[10], c[10], n1[999], n2[999], n3[999], s[10], i, j, k, f, t, r; //创建三个数组,用来存放1-9
t = 1;
for (i=1; i<=10; i++) //为三个数组赋值1-9
{
a[i] = i;
b[i] = i;
c[i] = i;
}
//### 列出符合“在1-9选三个数组成各位都不同”的第一个三位数 ###
for (i=1; i<4; i++) //第一层循环控制第一位数(百位),并且剔除掉超过400的数
{
for (j=1; j<10; j++) //二层循环控制第二位(十位)
{
if (j!=i) //保证第二位中不含第一位的数字(剔除十位中的百位数字)
{
for (k=1; k<10; k++) //三层循环控制第一位(个位)
{
if (k!=i && k!=j) //保证不含第一、二位中的数(剔除个位中百、十位中数字)
{
n1[t] = a[i]*100 + b[j]*10 +c[k]; //将三位不同数字组合成第一个三位数
n2[t] = n1[t] * 2; //第二个三位数
n3[t] = n1[t] * 3; //第三个三位数
t++; //确定符合条件的第一个三位数的个数,用于下面控制循环
}
}
}
}
}
//### 循环判断三个三位数所含数字在1-9中且各不相同 ##
for (f=1; f<t; f++) //一层循环,循环遍历上面求出的在数组n*[]中的元素
{
if (n1[f]>191 && n1[f]<334) //确定所求第一位三位数在191-334之间,其余不符合条件
{ //把三个三位数中全部9个数存放在数组s[]中
s[0] = n1[f] / 100;
s[1] = (n1[f] % 100) / 10;
s[2] = n1[f] % 10;
s[3] = n2[f] / 100;
s[4] = (n2[f] % 100) / 10;
s[5] = n2[f] % 10;
s[6] = n3[f] / 100;
s[7] = (n3[f] % 100) / 10;
s[8] = n3[f] % 10;
r = 0; //r赋值0(清零)
for (i=0; i<8; i++) //确保三个三位数中不含相同数字且不含数字0
{
for (j=i+1; j<9; j++)
{
if (s[i]==s[j] || s[i]==0 || s[j]==0) //如果有相同数字或有数字0则令r=1并跳转
{
r = 1;
goto A;
}
}
}
A:
if (r == 0) //如果各位数字均不同并且不含有数字0,则输出
{
printf("%d %d %d\n", n1[f], n2[f], n3[f]);
}
}
}
}
goto语句老师讲的时候直接跳过,通过这个题,温习goto语句的使用
下面是自己的想法,可能比较繁琐,但自己还是比较欣慰,好歹没放弃
#include<stdio.h>
int main()
{
int i,j,h;
for(i=123;i<=400;i++)
{
int k=i%10;
int x=i/10%10;
int y=i/100;
if(k==x||k==y||x==y||x==0||y==0||k==0)
continue;
else
{
j=2*i;
int a=j%10;
int b=j/10%10;
int c=j/100;
if(a==0||b==0||c==0||a==b||a==c||a==k||a==y||a==x||b==c||b==k||b==y||b==x||c==k||c==x||c==y)
continue;
else
{
h=3*i;
int w=h%10;
int e=h/10%10;
int r=h/100;
if(w==0||e==0||r==0||w==e||w==r||w==a||w==b||w==c||w==k||w==x||w==y||e==r||e==a||e==b||e==c||e==k||e==x||e==y||r==a||r==b||r==c||r==k||r==x||r==y)
continue;
else
printf("%d %d %d\n",i,j,h);
}
}
}
}
题目描述 津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。
输入格式 输入包括777行数据,分别表示周一到周日的日程安排。每行包括两个小于101010的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。
输出格式 一个数字。如果不会不高兴则输出000,如果会则输出最不高兴的是周几(用1,2,3,4,5,6,71, 2, 3, 4, 5, 6, 71,2,3,4,5,6,7分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。
输入输出样例 输入 #1
复制
5 3
6 2
7 2
5 3
5 4
0 4
0 6
输出 #1
复制
3
#include<stdio.h>
int main()
{
int t=0,i,x,y,k,j;
for(i=1;i<=7;i++)
{
scanf("%d %d",&x,&y);
if(t<x+y)
{
t=x+y;
k=i;
}
} //将最大的数字找出来,并记录最大数字所在的日子
if(t<=8) //再与临界数字8进行比较
j=0;
else
j=k;
printf("%d",j);
}
不高兴的津津问题是一个简单的找最大数字问题,循环与选择分支的共同作用,题目较简单,解题方法较多,但基本思路不变,即在限制条件中找出最大值和所在天数。
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300300300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。
为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%20%20%还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100100100元或恰好100100100元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。
例如111111月初津津手中还有838383元,妈妈给了津津300300300元。津津预计111111月的花销是180180180元,那么她就会在妈妈那里存200200200元,自己留下183183183元。到了111111月月末,津津手中会剩下333元钱。
津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
输入格式 121212行数据,每行包含一个小于350350350的非负整数,分别表示111月到121212月津津的预算。
输出格式 一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出−X-X−X,XXX表示出现这种情况的第一个月;否则输出到200420042004年年末津津手中会有多少钱。
注意,洛谷不需要进行文件输入输出,而是标准输入输出。
输入输出样例 输入 #1
复制
290
230
280
200
300
170
340
50
90
80
200
60
输出 #1
复制
-7
输入 #2
复制
290
230
280
200
300
170
330
50
90
80
200
60
输出 #2
复制
1580
#include<stdio.h>
int main()
{
int plan,i,x=0,c=0,k,t;
for(i=1;i<=12;i++)
{
k=0;
x+=300;
scanf("%d",&plan);
x=x-plan;
if(x<0)
{
k=1;
break; //出现不足情况直接跳出,标记该月。
}
t=x/100;
c+=t;
x=x%100;
}
if(k==0)
printf("%d",120*c+x);
else
printf("-%d",i);
}
这个题较复杂,重点是吧上交的钱和剩余的钱的思路理清。
P老师需要去商店买n支铅笔作为小朋友们参加NOIP的礼物。她发现商店一共有 333种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起 见,P老师决定只买同一种包装的铅笔。
商店不允许将铅笔的包装拆开,因此P老师可能需要购买超过nnn支铅笔才够给小朋 友们发礼物。
现在P老师想知道,在商店每种包装的数量都足够的情况下,要买够至少nnn支铅笔最少需要花费多少钱。
输入格式 第一行包含一个正整数nnn,表示需要的铅笔数量。
接下来三行,每行用222个正整数描述一种包装的铅笔:其中第111个整数表示这种 包装内铅笔的数量,第222个整数表示这种包装的价格。
保证所有的777个数都是不超过100001000010000的正整数。
输出格式 111个整数,表示P老师最少需要花费的钱。
输入输出样例 输入 #1
复制
57
2 2
50 30
30 27 输出 #1
复制
54输入 #2
复制
9998
128 233
128 2333
128 666 输出 #2
复制
18407输入 #3
复制
9999
101 1111
1 9999
1111 9999 输出 #3
复制
89991
#include<stdio.h>
int min(int a,int b)
{
if(a>b)
return b;
else
return a;
}
int main()
{
int n,x,y,t,i,a[3];
scanf("%d",&n);
for(i=0;i<3;i++)
{
scanf("%d %d",&x,&y);
if(n%x!=0)
a[i]=(n/x+1)*y;
else
a[i]=n/x*y;
}
printf("%d",min(min(a[0],a[1]),a[2]));
}
题目描述 已知:Sn=1+1/2+1/3+…+1/nS_n= 1+1/2+1/3+…+1/nSn=1+1/2+1/3+…+1/n。显然对于任意一个整数 kkk,当 nnn 足够大的时候,Sn>kS_n>kSn>k。
现给出一个整数 kkk,要求计算出一个最小的 nnn,使得 Sn>kS_n>kSn>k。
输入格式 一个正整数 kkk
输出格式 一个正整数 nnn
输入输出样例 输入 #1
复制
1
输出 #1
复制
2
#include<stdio.h>
int main()
{
int n,k;
double sum=0.0;
scanf("%d",&k);
for(n=1;;n++)
{
sum+=1.0/n;
if(sum>k)
break;
}
printf("%d",n);
}
小玉开心的在游泳,可是她很快难过的发现,自己的力气不够,游泳好累哦。已知小玉第一步能游2米,可是随着越来越累,力气越来越小,她接下来的每一步都只能游出上一步距离的98%。现在小玉想知道,如果要游到距离x米的地方,她需要游多少步呢。请你编程解决这个问题。
输入格式 输入一个数字(不一定是整数,小于100m),表示要游的目标距离。
输出格式 输出一个整数,表示小玉一共需要游多少步。
输入输出样例 输入 #1
复制
4.3 输出 #1
复制
3
#include<stdio.h>
int main()
{
float x,sum=0.0;
int i;
scanf("%f",&x);
for(i=0;;i++)
{
sum+=2*pow(0.98,i);
if(sum>x)
break;
}
printf("%d",i+1);
}
有一只小鱼,它平日每天游泳 250 公里,周末休息(实行双休日),假设从周 x(1≤x≤7)x(1\le x \le 7)x(1≤x≤7) 开始算起,过了 n(n≤106)n(n\le 10^6)n(n≤106) 天以后,小鱼一共累计游泳了多少公里呢?
输入格式 输入两个整数x,n(表示从周x算起,经过n天)。
输出格式 输出一个整数,表示小鱼累计游泳了多少公里。
输入输出样例 输入 #1
复制
3 10 输出 #1
复制
2000
#include<stdio.h>
int main()
{
int x,y,i,sum=0;
scanf("%d %d",&x,&y);
for(i=x;i<y+x;i++)
{
if(i%7==6||i%7==0)
continue;
else
sum=sum+250;
}
printf("%d",sum);
}