天天看点

算法入门 第3章 数组和字符串3.1 数组3.2字符数组

3.1 数组

读入一些整数,逆序输出到一行中,整数不超过100个。(用数组保存)

#include <stdio.h>
#define maxn 105


int a[maxn];

int main()
{
    int x,n=;
    while(scanf("%d",&x)==)
        a[n++]=x;
    for(int i=n-;i>=;i--){
        printf("%d ",a[i]);
    }
    printf("%d\n",a[]);
    return ;
}
           

运行结果

算法入门 第3章 数组和字符串3.1 数组3.2字符数组

注:在Window下,输入完毕后按Enter键,再按Ctrl+Z键,再按Enter键可以结束输入。在linux 下,输入完毕后按Ctrl+D键可结束输入。

提示:

1. “int a[maxn]”中 maxn必须为常量。

2. 比较大的数组应声明为全局变量,声明为局部变量数组程序可能异常退出。

3. 如果声明数组”int a[maxn],b[maxn]”,是不能赋值 b=a的,数组名为变量地址。如果过要将数组a 复制k个元素到数组b,可以这样做memcpy(b,a,sizeof(int)*k)。memcpy函数在C语言中需要包含头文件#include string.h ,C++则为 #include cstirng 。完全复制数组a到b则为memcpy(b,a,sizeof(a))

开灯问题

有n盏灯,编号为1~n。第1个人把所有灯打开,第二个人按下所有编号为2的倍数的开关,第3个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依次类推。一共有k个人,问最后有哪些灯开着?输入n和k,输出开着的灯的编号。k<=n<=1000.

样例输入:

7 3

样例输出:

1 5 6 7

【分析】

用a[1],a[2],….,a[n] 表示编号为1,2,3,….,n的灯是否开着。模拟这些操作即可。

#include<stdio.h>
#include<string.h>
#define   maxn 1010

int a[maxn];
int main(){
    int n,k,first;
    scanf("%d%d",&n,&k);

    memset(a,,sizeof(a));// 把数组a清零
    for(int i=;i<=k;i++){
        for(int j=;j<=n;j++)
        if(j%i==){
            a[j]=!a[j];
        }
    }
    for(int i=;i<=n;i++){
        if(a[i]){
            if(first){
                first=; //设置标志变量first,如果输出变量为第一个,则该变量不应该有空格
            }else{
               printf(" ");
            }
            printf("%d",i);
        }
    }
}
           

运行结果

算法入门 第3章 数组和字符串3.1 数组3.2字符数组

蛇形数组

在nxn方阵里填入1,2,…,n x n,要求填成蛇形。例如,n=4时方阵

10 11 12 1

9 16 13 2

8 15 14 3

7 6 5 4

【分析】

用二维数组存储题目中的方阵,从1开始填写。设“笔” 的坐标为(x,y),则一开始,笔的坐标为 x=0,y=n-1。笔的移动轨迹为下、左、上、右。不能填的条件是1.越界,2.下一个已填。

#include<stdio.h>
#include<string.h>
#define   maxn 10
int a[maxn][maxn];


int main(){
   int n;
   scanf("%d",&n);
   memset(a,,sizeof(a));
   int  i =;
   int x=,y=n-;
   a[x][y]=i++;
   while(i <=n*n){
       while((x+<n)&&a[x+][y]==){
          a[++x][y]=i++;
       }
       while(y->=&&a[x][y-]==){
          a[x][--y]=i++;
       }
       while(x->=&&a[x-][y]==){
          a[--x][y]=i++;
       }
       while(y+<n&&a[x][y+]==){
          a[x][++y]=i++;
       }
   }
   for(x=;x<n;x++){
       for(y=;y<n;y++){
        printf("%3d",a[x][y]);
       }
        printf("\n");
   }
   return ;
}
           

输出:

算法入门 第3章 数组和字符串3.1 数组3.2字符数组

提示:

1.先判断,再移动,尽量不要悔棋。

2.“&&”短路运算符防止访问非法内存。

3.2字符数组

竖式问题

找出所有形如 abc * de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。具体格式见样例输出(空格显示成点)。

输入

样例输入:2357

样例输出:

算法入门 第3章 数组和字符串3.1 数组3.2字符数组

【分析】

暴力求解,尝试所有的abc和cd

#include <stdio.h>
#include <string.h>
#include <stdio.h>
int main(){
   int count = ;
   char s[],buf[];
   scanf("%s",s);
   for(int abc = ; abc <= ;abc++ ){
       for(int de =;de<=;de++){
          int x = abc *(de%10),y=abc*(de/),z=abc*de;
          sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z);
          int ok =;
          for(int i=;i<strlen(buf);i++){
             if(strchr(s,buf[i])==NULL){
                 ok=;
             }
          }

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

总结:

1.scanf(“%s”,s)读入不含空格、TAB和回车符的字符串。数组名为地址。

2.

strchr(char *,int a)

,返回字符的位置,

strstr(char * a1, char *a2)

, a2在a1中的位置

3.

int sprintf( char *buffer, const char *format, [ argument] … );

将字符串输出到数组

4.strlen(s) 输出字符串长度。

TeX中的引号

在TeX中,左引号是““”,右引号是“‘’”。输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式。

#include<stdio.h>
int main(){
    int c,q=;
    while((c=getchar())!=EOF){
        if(c=='"'){
            printf("%s",q?"``":"''");
            q=!q;
        }else{
            printf("%c",c);
        }
    }
}
           
算法入门 第3章 数组和字符串3.1 数组3.2字符数组

继续阅读