1.开灯问题
有n盏灯,编号为1~n,第一个人把所有灯打开,第二个按下所有编号为2的倍数的开关(这些灯都被关掉),第三个人按下所有编号为3的倍数的开关,依次类推,一共有k个人,问最后有哪些灯开着?输入n和k,输出开着的灯的编号?
#include<stdio.h> #include<string.h> int a[1000]; //我们用数组来保存灯的状态 int main(void) { int n,k,i,j; int first=1;//最后的格式输出 memset(a,0,sizeof(a)); //把灯先设置为0,表示灯是关的 //然后模拟所有的关灯和开灯的操作 scanf("%d%d",&n,&k); //输入人数和灯数 for(i=1;i<=k;i++) { for(j=1;j<=n;j++) { if(j%i==0) a[j]=!a[j]; //如果满足条件,按动开关 } } for(j=1;j<=n;j++) { if(a[j]==1) { if(first) first=0; else printf(" "); printf("%d",j); } } printf("\n"); return 0; }
2.蛇形填数
在n*n的方阵填入1,2,...,n*n,要求填成蛇形,例如n=4
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
#include<stdio.h> #include<string.h> #define MAX 10 int a[MAX][MAX]; int main(void) { int x,y,n,tot; scanf("%d",&n); ` memset(a,0,sizeof(a)); tot=a[x=0][y=n-1]=1; //确定起点 while(tot<n*n) //判断有没有越界,注意下一个是不是0,还有如果x+1<n为假,则就不计算后面的,因为&&短路预算 { while(x+1<n && !a[x+1][y]) a[++x][y]=++tot; while(y-1>=0 && !a[x][y-1]) a[x][--y]=++tot; while(x-1>=0 && !a[x-1][y]) a[--x][y]=++tot; while(y+1<n && !a[x][y+1]) a[x][++y]=++tot; } for(x=0;x<n;x++) { for(y=0;y<n;y++) printf("%3d",a[x][y]); printf("\n"); } return 0; }
3.竖式问题
找出所有形如abc*de的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合,输入数字集合,输出所有竖式.
#include<stdio.h> #include<string.h> int main(void) { char s[20],buf[100]; int abc,de,x,y,z,ok; int num=0; scanf("%s",s); for(abc=111;abc<=999;abc++) { for(de=11;de<=99;de++) { x=abc*(de%10);y=abc*(de/10);z=abc*de; sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z); //写入字符串buf中 ok=1; for(int i=0;i<strlen(buf);i++) //比较buf和s中的字符是不是都有 { if(strchr(s,buf[i])==NULL) ok=0; } if(ok) //成功的标志 { printf("<%d>\n",++num); //计数 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",num); return 0; }
4.最长回文子串
输入一个字符串,求出其中最长的回文子串.
//分析,首先不适用使用scanf来输入字符串,因为碰到空格或者TAB就会停下 //于是我们可以使用fgets //先找最大回文子串的长度 #include<stdio.h> #include<string.h> #include<ctype.h> #define MAX 5000 char buf[MAX],s[MAX]; int main(void) { int n,m=0,max=0; int i,j,k; fgets(buf,sizeof(buf),stdin); //输入字符串 n=strlen(buf); //求字符串长度 for(i=0;i<n;i++) if(isalpha(buf[i])) s[m++]=toupper(buf[i]); //全部变成大写,方便判别 for(i=0;i<n;i++) { for(j=0;j<m;j++) { int ok=1; for(k=i;k<=j;k++) //s[k]的对称位置是s[i+j-k] { if(s[k]!=s[i+j-k]) ok=0; } if(ok&&j-i+1>max) max=j-i+1; } } printf("max=%d\n",max); return 0; } #include<stdio.h> #include<string.h> #include<ctype.h> #define MAX 5000 char buf[MAX],s[MAX]; int p[MAX]; int main(void) { int n,m=0,max=0; int x,y,i,j; fgets(buf,sizeof(buf),stdin); n=strlen(buf); for(i=0;i<n;i++) { if(isalpha(buf[i])) { p[m]=i; s[m++]=toupper(buf[i]); } } for(i=0;i<m;i++) { for(j=0;i-j>=0&&i+j<m;j++) //从内部向外分开,奇数情况,aba { if(s[i-j]!=s[i+j]) break; if(j*2+1>max) { max=j*2+1; x=p[i-j]; y=p[i+j]; } } for(j=0;i-j>=0&&i+j+1<m;i++) //从内部向外分开,偶数情况,考虑aabb { if(s[i-j]!=s[i+j+1]) break; if(j*2+2>max) { max=j*2+2; x=p[i-j]; y=p[i+j+1]; } } } for(i=x;i<=y;i++) printf("%c",buf[i]); printf("\n"); return 0; }
习题
分数统计
任务1 分数为不吵为100的非负整数
#include<stdio.h> #include<string.h> int main(void) { int num[110]; int x; int ans; int max=0; memset(num,0,sizeof(num)); while(scanf("%d",&x)==1) { num[x]++; } for(int i=0;i<=100;i++) { if(num[i]>=max) { max=num[i]; ans=i; } } for(int i=0;i<101;i++) { if(num[i]==max) printf("%d ",i); } printf("\n"); return 0; }
任务2 输入为不超过100的非负实数
//习题3.1,分数统计(stat) #define LOCAL #include<stdio.h> #include<string.h> #include<math.h> #ifndef MAX #define MAX 10000+1 #endif int a[MAX]; int main(){ //从本地读取文件(重定向),不用每次都进行数据输入 #ifdef LOCAL freopen("data.txt","r",stdin); #endif memset(a,0,sizeof(a)); double degree; while(scanf("%lf",°ree) == 1){ //直接double强制转化为int会出现问题,如4.9999999999,应为5,但会是4.9 //使用floor进行四舍五入可以解决这个问题 double m = degree * 100; int n = floor(m+0.5); a[n] += 1; } int i,max = a[0]; int tmp[MAX]; memset(tmp,0,sizeof(tmp)); for(i=1; i <= MAX; i++){ if(a[i] > max){ max = a[i]; } } int j = 0; for(i = 0; i < MAX; i++){ if(a[i] == max){ tmp[j] = i; j++; } } for (i = 0; i < j; ++i) { double temp = tmp[i]*0.01; printf("%.2f\n",temp); } return 0; }
单词的平均长度
#include<stdio.h> int main(void) { char ch; int num=0,words=0; int inword=0; while((ch=getchar())!=EOF) { if(isalpha(ch)) num++; if(!isspace(ch)&&!inword) { inword=1; words++; } if(isspace(ch)&&inword) inword=0; } printf("The averge word is %.2f\n",(double)num/words); return 0; }
乘积的末3位
输入若干个整数(可以是正数、负数或者零),输出它们的乘积的末3位。这些整数中会混入一些由大写字母组成的字符串,你的程序应该忽略它们。提示:试试看,在执行scanf("%d")时输入一个字符串会怎样?
输入:AB123CC BB123123321321 DDD22 888888888888888888888888888ZZ -411B
输出:968
输入:AA-11BBB D2CCC
输出:-22
假定末3位是指,不足3位就输出数字本身,如果是负数则包括负号,比如结果是-12,则输出-12;结果是11,则输出11,结果是0,则输出0;
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #define N 100000 #define M 5000 #define L 5 char input[N]; char str[M]; char tmp[L]; char rev[L]; int main(void) { int i, len, k; int flag = 1; int product = 1; char *p = NULL; fgets(input, sizeof (input), stdin); p = input; while (sscanf(p, "%s", str) == 1) { len = k = 0; for (i = strlen(str)-1; i != -1; i--) { if (len != 3 && 1 == isdigit(str[i])) tmp[len++] = str[i]; if (str[i] == ‘-‘) { flag = -flag; break; } } tmp[len] = ‘\0‘; while (len > 0) rev[k++] = tmp[--len]; rev[k] = ‘\0‘; product *= atoi(rev); product %= 1000; p += strlen(str)+1; while (*p == ‘ ‘) p++;/* 滤空 */ } printf("%d\n", product < 100 ? product*flag : product); return 0; }
计算器
编程程序读入一行恰好包括一个+或-或*的表达式,输出它的值。运算符保证是二元运算符,且两个运算数均不超过100的非负整数。运算数和运算符可以紧挨也可以有一个或多个空格、TAB隔开。行首尾均可以有空格。提示:选择合适的输入方法可以将问题简化。
#include <stdio.h> #define N 1000 char str[N]; int main(void) { char *p = NULL; int op1, op2; fgets(str, sizeof(str), stdin);//it will contains ‘\n‘; for (p = str; *p != ‘\n‘; p++) { if (*p == ‘+‘ || *p == ‘-‘ || *p == ‘*‘) break; } if (*p != ‘\n‘){ switch(*p) { case ‘+‘: sscanf(str, "%d + %d", &op1, &op2); printf("%d\n", op1+op2); break; case ‘-‘: sscanf(str, "%d - %d", &op1, &op2); printf("%d\n", op1-op2); break; case ‘*‘: sscanf(str, "%d * %d", &op1, &op2); printf("%d\n", op1*op2); break; } } return 0; }
输入一个n*n字符矩阵,把它左旋90度后输出
#include <stdio.h> #define N 100 char a[N][N]; int main(void) { int n; int i, j; scanf("%d", &n); for (i = 0; i != n; i++) { for (j = 0; j != n; j++) scanf("%s", &a[i][j]); } for (j = n-1; j != -1; j--) { for (i = 0; i != n; i++) printf("%c ", a[i][j]); printf("\n"); } return 0; }
进制转换
#include <stdio.h> voidtrans(int n, int b) { if (n >= b) trans(n/b, b); printf("%d", n%b); } void trans(int n, int b); int main(void) { int b, n; scanf("%d %d", &b, &n); trans(n, b); printf("\n"); return 0; } //非递归 #include <stdio.h> #define N 100 int a[N]; int main(void) { int b, n; int k = 0; int i; scanf("%d %d", &b, &n); while (n >= b) { a[k++] = n%b; n /= b; } a[k++] = n%b; for (i = k-1; i != -1; i--) printf("%d", a[i]); printf("\n"); return 0; } //输出基数b( 2 <= b <= 10)和正整数n(b进制),输出n的十进制表示 #include <stdio.h> #include <string.h> #define N 100 char str[N]; int main(void) { int n, i, k, tmp; int res = 0; scanf("%d %s", &n, str); for (i = strlen(str)-1; i != -1; i--) { tmp = str[i]-‘0‘; k = strlen(str)-1-i; while(k--) tmp *= n; res += tmp; } printf("%d\n", res); return 0; }