算法入门笔记------------Day2

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",&degree) == 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;
}

  

上一篇:(转)spring boot注解 --@EnableAsync 异步调用


下一篇:springmvc+spring+mybatis+maven项目集成shiro进行用户权限控制【转】