逆序输出
读入一些整数然后逆序输出,将你所输入的每个数字存入到数组a[maxn]中,然后利用for循环逆序输出,输入完了以后别忘了先按回车再按crtl+z,强制输出,要不然会无限输入的2333.这段程序运行是这样的:(给你个例子( ̄▽ ̄)")如果输入12 33 55 89 ,则输出 89 55 33 12.【主要是a[n++]=x这个地方很高效】
#include<stdio.h>
#define maxn 105
int a[maxn];
int main()
{
int x,n=0;
while(scanf("%d",&x)==1)
a[n++]=x;
for(int i=n-1;i>=1;i--)
printf("%d ",a[i]);
printf("%d\n",a[0]);
return 0;
}
开灯问题
有n个灯,编号为1-n,第1个人把所有灯打开,第2个把2的倍数的灯号打开以此类推。一共k人,最后有哪些灯亮着。
一开始用memset把数组a清零,模拟一开始所有灯都是关了的状态,然后我们发现改变状态灯都是 灯的数量n能被1到k整除的灯,比如题目例子中7 3,第一次改变的是1-7,第二次,2,4,6,第三次3,6;刘汝佳老师用的是a[j]=!a[j]来进行对灯状态的改变,a[j]=!a[j]这个语句就是非零即真,如果a[j]为1那么进行完语句之后就是0,反之为0,最后是1.简言之就是0变成1,1变成0.
拿书上例子7 3来说,①i=1,j=1,j%i==0,a[j]=1(因为memset清零了)j一直到7,都能被整除,代表所有灯都亮。②i=2,j=1不整除不执行语句,所以a[j]还是1,j=2,整除a[j]=0;以此类推,最后a[2],a[4],a[6]=0,其余为1;③i=3情况也是一样的,a[3],a[6]整除,它们再变,a[3]=0,a[6]=1。然后就是控制空格的问题了,a[i]肯定!=0,所以第一次执行这里的时候first=0,此后first一直=0,就是只有第一个输出i,剩下的因为first=0,输出空格+i,最后再来个\n。完美~
#include<stdio.h>
#include<string.h>
#define maxn 1005
int a[maxn];
int main()
{
int n,k,first=1;
memset(a,0,sizeof(a));
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
for(int j=1;j<=n;j++)
if(j%i==0)
a[j]=!a[j];
for(int i=1;i<=n;i++)
if(a[i])
{
if(first)
first=0;
else
printf(" ");
printf("%d",i);
}
printf("\n");
return 0;
}
蛇形填数
二维数组的应用。一开始我们先把n*n的矩阵全部填充0:memset(a,0,sizeof(a)),然后将最右上角的那个0赋值1,tot也赋值成1:tot=a[x=0][y=n-1]=1;tot进行填数,蛇形填数的最后一个数字一定是n*n,所以while(tot<n*n),然后蛇形填数肯定都是先往下走,再往左走,再往上走,再往右走,我们需要一个界限不是吗?要不然它不就会一直往一个地方走而不变方向,而这个界限举例一下while(x+1<n&&!a[x+1][y]),从最右上角开始往下走,x每+1,就走了一步,x+1肯定<n,而!a[x+1][y]和上题一样,一开始我们不是将a[maxn][maxn]清零了吗,就相当于一个界限了,超出n*n的部分都不是0,在n*n里面这个区域里才都是0,满足两个条件才执行语句。然后最右上角a[0][n-1]=1,往下走一个a[1][n-1]就从0变成1,然后进行tot++,赋值a[1][n-1]=2,以此类推。
#include<stdio.h>
#include<string.h>
#define maxn 20
int a[maxn][maxn];
int main()
{
int n,x,y,tot=0;
scanf("%d",&n);
memset(a,0,sizeof(a));
tot=a[x=0][y=n-1]=1;
while(tot<n*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("%4d",a[x][y]);
printf("\n");
}
return 0;
}
竖式问题
拿书上例子来说输入的2357是一个集合,我们可以把这个集合取名A={2,3,5,7},只要abc,de,x,y,z的元素在这个集合里就算一个合法的竖式。【一开始我没弄明白= =】,比如书上例子abc=775,元素是7,5在集合A中,de=33,元素是3,在集合A中,x=2325,元素是2,3,5在集合A中,y同,z=25575,元素是2,5,7在集合A中。然后abc是个三位数所以从100-999里去找,de是个两位数从10-99里去找。(为什么书上写的是111-999和11到99,这......有问题吧)sprintf(buf,"%d%d%d%d",abc,de,x,y,z)就是将abc,de,x,y,z,变成字符串存入到buf中,比如例子中abc=775,de=33,x=2325,y=2325,z=25575,执行语句之后就是buf[i]={"775332325232525575"},然后strchr(s,buf[i])就是找buf[i]在字符串s中(首次)的位置,如果找不到就返回NULL.
#include<stdio.h>
#include<string.h>
int main()
{
int count=0;
char s[20],buf[99];
scanf("%s",s);
for(int abc=100;abc<=999;abc++)
for(int de=10;de<=99;de++)
{
int x=abc*(de%10),y=abc*(de/10),z=abc*de;
sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z);
int ok=1;
for(int i=0;i<strlen(buf);i++)
if(strchr(s,buf[i])==NULL)
ok=0;
if(ok)
{
printf("<%d>\n",++count);
printf("%5d\n",abc);
printf("X%4d\n",de);
printf("------\n");
printf("%5d\n",x);
printf("%4d\n",y);
printf("------\n");
printf("%5d\n",z);
printf("\n");
}
}
printf("The number of solutions = %d\n",count);
return 0;
}
TeX中的引号
gets竟然被废除了啊w(゚Д゚)w,这么可怜的吗,我还挺常用它来着......
#include<stdio.h>
int main()
{
int q=1,c;
while((c=getchar())!=EOF)
{
if(c=='"')
{
printf("%s",q ? "“" : "''");
q=!q;
}
else
printf("%c",c);
}
return 0;
}