赞
踩
#include<stdio.h> #define maxn 105 int a[maxn];//数组一般会声明得稍大一些,防止越界 int main(){ int x, n = 0; while(scanf("%d",&x) ==1){ //当输入不为int型数字时停止 a[n++] = x; //n++先用n计算表达式,再将n加1;++n先将n加1,再计算表达式。 } for(int i = n-1; i >= 1; i--){ printf("%d ", a[i]); } printf("%d\n",a[0]); return 0; }
用语句“int a[maxn]”声明一个包含maxn个整型变量的数组,即a[0],a[1],…,a[maxn-1],但不包含a[maxn]。maxn必须是常数,不能是变量。只有“int a[maxn]”在放外面时,数组a才可以开得很大。
数组不能够进行赋值操作,如果要从数组a复制k个元素到数组b,可以用:memcpy(b,a,sizeof(int)*k)(需要包含头文件string.h),如果要把数组a全部复制到数组b中,可以用:memcpy(b,a,sizeof(a)).
开灯问题: 有n盏灯,编号为1~n。第1个人把所有灯打开,第2个人按下所有编号为2的倍数的开关(这些灯将被关掉),第3个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?输入n和k,输出开着的灯的编号。k≤n≤1000。
#include <stdio.h> #include <string.h> #define maxn 1005 int a[maxn]; int main() { int n,k,first = 1; memset(a,0, sizeof(a));//把数组a清零 scanf("%d%d", &n, &k); for(int i = 1; i<=k; i++){ for (int j = i; j <=n ; j+=i) { a[j] = (a[j]+1)%2;//0变1,1变0,这样省去了用if判断 } } for (int j = 1; j <=n ; j++) { if(a[j]==1){ if(first == 1) //标志变量first表示当前要输出的变量是否为第一个。第一个变量前不应有空格,但其他变量都有。 first =0; else printf(" "); printf("%d",j); } } return 0; }
在很多情况下,最好是在做一件事之前检查是不是可以做,而不要做完再后悔。因为“悔棋”往往比较麻烦。
C语言中的字符型用关键字char表示,它实际存储的是字符的ASCII码。字符常量可以用单引号法表示。在语法上可以把字符当作int型使用。
“scanf("%s", s)”会读入一个不含空格、TAB和回车符的字符串,存入字符数组s。注意s前面没有“&”符号。如果是字符串数组chars[maxn] [maxl],可以用“scanf("%s", s[i])”读取第i个字符串。
可以用sprintf把信息输出到字符串,用法和printf、fprintf类似。但应当保证字符串足够大,可以容纳输出信息。
C语言中的字符串是以“\0”结尾的字符数组,可以用strlen(s)返回字符串s中结束标记之前的字符个数。
竖式问题: 找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。
#include<stdio.h> #include<string.h> int main() { int count = 0; char s[20], buf[99]; scanf("%s", s); for(int abc = 111; abc <= 999; abc++) for(int de = 11; de <= 99; de++) { int x = abc*(de%10), y = abc*(de/10), z = abc*de; sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z); int ok = 1; for(int i = 0; i < strlen(buf); i++) if(strchr(s, buf[i]) == NULL) ok = 0;//strchr的作用是在一个字符串中查找单个字符 if(ok) { printf("<%d>\n", ++count); printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc, de, x, y, z); } } printf("The number of solutions = %d\n", count); return 0; }
“scanf("%s")”可以输入字符串,但它碰到空格或者TAB就会停下来。虽然下次调用时会输入下一个字符串,可是不知道两次输入的字符串中间有多少个空格、TAB甚至换行符。
两种方法读取带空格、TAB或换行符的字符串:
1. “fgetc(fin)”读取一个打开的文件fin,读取一个字符,然后返回一个int值。如果文件结束,fgetc将返回一个特殊标记EOF。从标准输入读取一个字符可以用getchar,它等价于fgetc(stdin)。
不同操作系统的回车换行符是不一致的,在使用fgetc和getchar时,应该避免写出和操作系统相关的程序。
2. 使用“fgets(buf, maxn, fin)”读取完整的一行,其中buf的声明为char buf[maxn]。这个函数读取不超过maxn-1个字符,然后在末尾添上结束符“\0”,因此不会出现越界的情况。一旦读到回车符“\n”,读取工作将会停止,而这个“\n”也会是buf字符串中最后一个有效字符(再往后就是字符串结束符“\0”了)。
表达式式"a?b:c"的含义是:当a为真时值为b,否则为c
常量数组并不需要指明大小,编译器可以完成计算。
#include<ctype.h>
if(isalpha(ch))//判断字符ch是否为字母,函数isalpha()包含在库ctype.h中
例题3-4 猜数字游戏的提示
实现一个经典"猜数字"游戏。给定答案序列和用户猜的序列,统计有多少数字位置正确(A),有多少数字在两个序列都出现过但位置不对(B)。
输入包含多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干猜测序列。猜测序列全0时该组数据结束。n=0时输入结束。
#include <stdio.h> #include <cstring> #define maxn 100005 int ans[maxn]; int ges[maxn]; int A[maxn]; int B[maxn]; int main() { int n,game=0; memset(ans,0, sizeof(ans));//初始化数组 memset(ges,0, sizeof(ges)); memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); while(scanf("%d",&n)&& n != 0){ //当输入n==0时停止 game++; int tag1[15] = { 0},tag2[15] = { 0}; for(int i =0; i<n; i++){ scanf("%d",&ans[i]);//输入答案 tag1[ans[i]]++;//记录答案中每个数字出现的次数 } int flag = 0,tot = 0; while(flag != n){ //当输入全0时一组结束 flag =0; for(int i =0; i<n; i++){ scanf("%d",&ges[i]); tag2[ges[i]]++;//记录每次猜测中每个数字出现的次数 if(ges[i]==0) flag++; } for(int i =0; i<n; i++){ if(ges[i]==ans[i]) A[tot]++;//记录每组猜测中位置正确的数量 } for(int i =1; i<10; i++){ B[tot] +=((tag1[i]>tag2[i])? tag2[i] :tag1[i]); //记录在两个序列都出现过但位置不对的数量 tag2[i] = 0;//用完归零 } B[tot] -= A[tot]; tot++; } printf("Game %d:\n",game); for (int i = 0; i < tot-1; ++i) { printf("(%d,%d)\n",A[i],B[i]);//输出每组结果 } memset(tag1,0, sizeof(tag1));//重置数组 memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); } return 0; } /* 4 1 3 5 5 1 1 2 3 4 3 3 5 6 5 5 1 6 1 3 5 1 3 5 5 0 0 0 0 10 1 2 2 2 4 5 6 6 6 9 1 2 3 4 5 6 7 8 9 1 1 1 2 2 3 3 4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。