第十三周周报
朱丽
本周主要目的:回头整理以前做过的题,会做的题重新做一遍,提升速度,加深印象。以前没做出的题继续思考,争取做出来。
12月17日:做数据
12月18日:
第一题:实数输出

#include<stdio.h>
#define pi 3.1415926535897933
int main()
{
int r;
double s;
scanf("%d",&r);
if((1<=r)&&(r<=10000))
{
s=pi*r*r;
}
printf("%0.7f\n",s);
return 0;
}

第二题:循环,判断
问题描述
给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个。
输入格式
第一行包含一个整数n。
第二行包含n个非负整数,为给定的数列,数列中的每个数都不大于10000。
第三行包含一个整数a,为待查找的数。
输出格式
如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。
样例输入
6
1 9 4 8 3 9
9
样例输出
2
数据规模与约定
1 <= n <= 1000。
解题思路:
如果数列中有和a相同的数,则定义一个数组m[100]用于存与a相同的数的位置。
如果数列中的数与a不相同,再定义一个数组了l[100]将-1存入数组l[100]中。
最后通过判断数组l[100]中的-1的个数是否等于n,等于就输出-1,不相等就输出m[0]( a在数列中出现了,输出它第一次出现的位置m[0])。
改进:程序中用了3个数组,其中经过改进发现数组l[100]可以不要。只需要将最后判断输出语句换为if(n-j<n)就可以了。意思为如果数组m[100]中的个数大于等于1就表示数列存在与a相同的数,输出m[0]。反之输出-1.
#include<stdio.h>
int main()
{
int n,b[100],a,i,j=0,k=0,m[100],l[100];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
scanf("%d",&a);
for(i=0;i<n;i++)
{
if(b[i]<=10000)
{
if(b[i]==a)
{
m[j]=i+1;
j++;
}
else
{
l[k]=-1;
k++;
}
}
}
if(k==n)
{
printf("-1");
}
else
{
printf("%d",m[0]);
}
printf("\n");
return 0;
}

改进后的程序
#include<stdio.h>
int main()
{
int n,b[100],a,i,j=0,m[100];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
scanf("%d",&a);
for(i=0;i<n;i++)
{
if(b[i]<=10000)
{
if(b[i]==a)
{
m[j]=i+1;
j++;
}
}
}
if(n-j<n)
{
printf("%d",m[0]);
}
else
{
printf("-1");
}
printf("\n");
return 0;
}.
12月19日:
第三题:数组,循环,判断(全对有点难,可跳过)

解题思路:利用两个数组存需要处理的数,一个数组存一列数。再利用冒泡排序中循环的思想,先定第一行,循环后面的行。接着又跳到第二行,继续循环后面的行…….
#include<stdio.h>
int main()
{
int N,i,j,m=0,x[50],y[50];
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%d%d",&x[i],&y[i]);
}
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
{
if(x[i]+x[j]==y[i]+y[j])
m++;
}
}
printf("%d\n",m);
return 0;
}

第一题:

辗转相除,余数为0,得到结果最大公约数rn-1;
#include<stdio.h>
int main()
{
int m,n,r,t,p,lcm=0;
scanf("%d%d",&m,&n);
p=m*n;
while((t=m%n)!=0)
{
m=n;
n=t;
}
lcm=p/n;
printf("%d\n",lcm);
return 0;
}

12月20,21:做数据
12月22日:
第二题:(二维数据,循环)
题目:
给定一个N阶矩阵A,输出A的M次幂(M是非负整数)
例如:
A =
1 2
3 4
A的2次幂
7 10
15 22
输入格式
第一行是一个正整数N、M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数
接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值
输出格式
输出共N行,每行N个整数,表示A的M次幂所对应的矩阵。相邻的数之间用一个空格隔开
样例输入
2 2
1 2
3 4
样例输出
7 10
15 22
思考:想一想当次数很高时,有没有地方可以优化。
解题思路:此题主要的重点是理解矩阵相乘的运算规则,第一行乘以第一列,第一行乘以第二列……分别为结果矩阵的第一行数,依次递推。
注意:此题容易出错的是用循环计算的时候应该是三个循环,而不是两个循环。
#include<stdio.h>
int main()
{
int n,N,M,i=0,j,k,sum=0,m[30][30]={0}
,A[35][35]={0};
scanf("%d%d",&N,&M);
n=N;
if(1<=N&&N<=30&&1<=M&&M<=5)
{
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
scanf("%d",&A[i][j]);
}
}
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
printf("%d ",m[i][j]) ;
}
if(n/N==1)
{
printf("\n");
}
}
printf("\n");
return 0;
}
int cheng(int m,int a[35][35])
{
int i,j,k;
if(m=2)
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
for(k=0;k<n;k++)
a[i][j]=a[i][j]+A[i][k]*A[k][j] ;
}
}
}
if(m>2&&m<=5)
{
a[i][j]=cheng(m-1)*a[i][j];
}
return (a[i][j])
}

[问题描述]
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3...
当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为6时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 .....
我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离(不能斜线方向移动)
输入为3个整数w m n,空格分开,都在1到10000范围内
要求输出一个整数,表示m n 两楼间最短移动距离。
[样例输入]
6 8 2
[样例输出]
4
[样例输入]
4 7 20
[样例输出]
5
解题思路:
1.用m,n分别除以w,取各自的整数,余数。
(行数)
2.如果余数为0,则m,n所处的行数为m,n除以w取整的值;
如果余数不为0,则m,n所处的行数为m,n除以w取整的值加1;
(列数)
3.如果余数为0且行数为奇数,则m,n所处的列数为w;
如果余数为0且行数为偶数,则m,n所处的列数为1;
4.如果余数不为0且行数为奇数,则m,n所处的列数为余数;
如果余数不为0且行数为偶数,则m,n所处的列数为w-余数+1;
(结果)
5.如果m,n为相邻的两行,则结果为行差+列差;
如果m,n为不相邻的两行,则结果为行差+列差-1;
#include<stdio.h>
#include<math.h>
int main()
{
int t1,s1,t2,s2,r1,r2,j1,j2,r,j,root;
int w,m,n;
scanf("%d%d%d",&w,&m,&n);
t1=m/w;
s1=m%w;
t2=n/w;
s2=n%w;
if(s1==0)
{
r1=t1;
}
else
{
r1=t1+1;
}
if(s1==0)
{
if(t1%2==0)
{
j1=1;
}
else
{
j1=w;
}
}
else
{
if(t1%2==0)
{
j1=w-s1+1;
}
else
{
j1=s1;
}
}
if(s2==0)
{
r2=t2;
}
else
{
r2=t2+1;
}
if(s2==0)
{
if(t2%2==0)
{
j2=1;
}
else
{
j2=w;
}
}
else
{
if(t2%2==0)
{
j2=w-s2+1;
}
else
{
j2=s2;
}
}
r=r1-r2;
j=j1-j2;
if(abs(r)==1)
{
root=abs(r)+abs(j);
}
else
{
root=abs(r)+abs(j)+1;
}
printf("%d\n",root);
return 0;
}
