zoukankan      html  css  js  c++  java
  • 算法入门笔记------------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("
    ");
            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("
    ");
            }
            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>
    ",++num);         //计数
                                printf("%5d
    X%4d
    -----
    %5d
    %4d
    -----
    %5d
    
    ",abc,de,x,y,z);
                        }
                }
            }
            printf("The number of solutions =%d
    ",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
    ",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("
    ");
            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("
    ");
            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 ",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
    ",(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] = '';
    		while (len > 0)
    			rev[k++] = tmp[--len];
    		rev[k] = '';	
    		product *= atoi(rev);
    		product %= 1000;
    		p += strlen(str)+1;
    		while (*p == ' ') p++;/* 滤空 */			
    	}
    	printf("%d
    ", 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 '
    ';
    	
    	for (p = str; *p != '
    '; p++) {
    		if (*p == '+' || *p == '-' || *p == '*')
    			break;
    	}
    	if (*p != '
    '){
    		switch(*p) {
    		case '+':
    			sscanf(str, "%d + %d", &op1, &op2);
    			printf("%d
    ", op1+op2);
    			break;
    		case '-':
    			sscanf(str, "%d - %d", &op1, &op2);
    			printf("%d
    ", op1-op2);
    			break;
    		case '*':
    			sscanf(str, "%d * %d", &op1, &op2);
    			printf("%d
    ", 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("
    ");
    	}
    	
    	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("
    ");
    	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("
    ");
    	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
    ", res);
    	
    	return 0;
    }
    

      

  • 相关阅读:
    CPU Cache与缓存行
    linux 查看命令总结
    idea自个常用工具的总结
    《人月神话》
    啊哈,翻转
    Scrapy爬虫之豆瓣TOP250
    87的100次幂除以7的余数是多少
    python之sqlite3 用法详解
    Sublime Text 3 插件SublimeLinter/PEP8安装&配置,检查代码规范
    urlparse之urljoin() 爬虫必备
  • 原文地址:https://www.cnblogs.com/SqLver/p/4931578.html
Copyright © 2011-2022 走看看