码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-11-02 23:05:38      阅读:406      评论:0      收藏:0      [点我收藏+]

标签:

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;
}

  

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

标签:

原文地址:http://www.cnblogs.com/SqLver/p/4931578.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!