人文实验室任务第一次题解

B

我的原代码

#include <stdio.h>

int main()

{

inta,b,c;

scanf("%d %d %d",&a,&b,&c);

printf("%8d %8d %8d\n",a,b,c);

return 0;

}

注意一点就是要加空格.

C我的原代码

#include <stdio.h>

int main()

{

char chr;

scanf("%c",&chr);

int i=1,j;

for(i;i<=5;i++)

{

for(j=1;j<=abs(3-i);j++)

{

printf(" ");

}

for(j=1;j<=5-2*abs(3-i);j++)

{

printf("%c",chr);

}

printf("\n");

}

return 0;

}

题解:关键就是根据例子找规律

主要要思路先写一个可以循环n次的循环,然后在里面写一个循环

用来输出字符输出多少字符观察例子可以发现是一个对称图像所以,以第三行为基准点在观察和最近的上面或者下面一行差的字符数可以得出一个关系式子:5-|2*(3-i)|个

为了符合这个式子所以我们循环变量j=1开始。我们就得到了雏形。然后我们就考虑输出空格了同理会得到一个输出个|(3-i)|个空格的式子。

D

我的原码

#include <stdio.h>

int main()

{

int a,b;

double c;

scanf("%d%d",&a,&b);

c=1.0*a/b;

printf("%.9lf",c);

return 0;

}

题解:简单的计算flaot的精确度不够要用double类型。

E

我的源代码

#include <stdio.h>

int main()

{

int n,a[n];

scanf("%d",&n);

for(int i=0;i<n;i++)

{

scanf("%d",&a[i]);

}

double sum1=0.0;

double sum2=0.0;

for(int i=0;i<n;i++)

{

sum1+=a[i];

sum2+=sum2;

}

printf("%.0lf",sum2);

return 0;

}
题解:

易错:比如说这个例子1 2 3容易简单的想成1+2+3=6就是不等于10,一直懵逼。

正确算法是1+1+2+1+2+3=10

吃第一道菜的好汉度是1 吃完第二道菜后的好感度是1+2=3然后吃完第三道菜的好感度是1+2+3=6 所以总的愉悦值是所有好感度之和为10.

所以要设置俩个三个变量sum1,sum2存储好感度和愉悦值用一个循环来刷新每次吃完一道菜的好感度sum1,再累加给sum2.循环完后sum2就是总的愉悦值

没啥好说的直接上代码

#include <stdio.h>

int main()

{

int n,i;

scanf("%d",&n);

int a;

double sum=0.0;

for(i=1;i<=n;i++)

{

scanf("%d",&a);

sum=sum+a;

}

double sum1;

sum1=1.0*sum/n;

printf("%.0lf %.5lf",sum ,1.0*sum/n);

return  0;

}

简单的数学计算.

没啥好说的简单的数学计算直接上代码

#include <stdio.h>

int main()

{

double x,a,b,c,d;

double sum;

scanf("%lf%lf%lf%lf%lf",&x,&a,&b,&c,&d);

sum=1.0*a*x*x*x+b*x*x+c*x+d;

printf("%.7lf",sum);

return 0;

}

H

我的代码

#include <stdio.h>

int s[50];

int F(int x)

{ if(s[x])return s[x];

if(x==1||x==2) return s[x]=1;

return s[x]=F(x-1)+F(x-2);

}

int main()

{

int n;

scanf("%d",&n);

printf("%d",F(n));

return 0;

}

我用的是递归调用解决的

从第三项开始每一项的值等于前俩项之和用递归就可以很好的解决

但是单纯用递归会超时间,所以要用一个数组存储每一项的值,

思路的话题目就很明显没啥好说的.

I:

我的代码:

 #include <stdio.h>

int main(){

int n,m;

int sum=0;

scanf("%d %d",&m,&n);

for(m;m<=n;m++)

{

if(m%2!=0)

{

sum=sum+m;}

}

printf("%d",sum);

return 0;

}

就是用了一个简单的循环最直接从m到n依次遍历找除以二余数不为0的数直接累加.

J我的代码

#include <stdio.h>

int main()

{

int a;

scanf("%d",&a);

while(a)

{

int sum=0;

sum=a%10;

printf("%d ",sum);

a=a/10;

}

 return 0;

}

题解:这里用了一个while循环直接用来充当循环继续下去的条件

每次循环我们就把a的个位数通过取余取出来,并且每循环一次我们就给a去掉一位数,

当a被除成0了数字也取完了,循环也会自动结束.

K

我的原代码

#include <stdio.h>

int main(){

int n;

scanf("%d",&n);

int p[100],q[100];

p[1]=1,q[1]=2;

int i,j;

for(i=1,j=1;i<=n,j<=n;i++,j++)

{

q[i+1]=q[i]+p[j];

p[j+1]=q[i];

}

double sum=0;

for(i=1,j=1;i<=n,j<=n;i++,j++)

{

sum=sum+1.0*q[i]/p[j];

}

printf("%.4lf\n",sum);

return 0;}

题解;根据题意我们可以设置俩个数组p和q根据题意可以知道需要用一个循环根据题意p和q的关系 qi+1=qi+pi,pi+1=qi.

每次循环给数组去q[i+1]p[i+1]赋值然后在用一个循环求q[i]和p[i]的商的和.

L

我的代码

#include <stdio.h>

int main()

{

int n,j=0,a=0,b=0;

char c;

scanf("%d\n",&n);

char s[105];

for(int i=0;i<n;i++)

{

scanf("%s",s);

for(int j=0;(c=s[j])!='\0';j++)

{

if(c=='A') a+=1;

if(s[j]=='L'&&s[j+1]=='L'&&s[j+2]=='L') b=1;

}

if(a>=2||b==1){

 printf("NO\n");

 a=0;b=0;}

else {

printf("YES\n");

a=0,b=0;}

}

return 0;

}

题解:设置俩个变量a,b来判断出勤是否合格,写一个循环用来输入字符在写一个循环遍历所有字符由题意可知如果出现一个A我们就给a加1如果来连续有三个L就给b加1,循环遍历完所有字符后就根据a和b值来判断。易错点就是每次判断完后记得要刷新a,b为0.

M我的原代码

#include <stdio.h>

#include <math.h>

int isprime(int x,int y)

{

int cnt=0;

for(x;x<=y;x++)

{

int flage=1;

if(x==1) flage=0;

for(int i=2;i<=sqrt(x);i++)

{

if(x%i==0)

{

flage=0;

break;

}  

}

while(flage)

{

cnt++;

flage=0;

}

}

return cnt;

}

int main()

{

int x,y,t,number;

scanf("%d%d",&x,&y);

if(x>y)

{

t=x;

x=y;

y=t;

}

number=isprime(x,y);

printf("%d",number);

return 0;

}

题解:核心部分是写了一个找素数的函数,定义了一个flag标记,在找素数的函数isprime()里写了俩个循环用来寻找x到y的素数,内层是判断x是否为素数有一个数学结论,是直接从2遍历到根号x提高效率。根据x能否整除来赋值flag=1,然后在用一个while(flag)来cnt+1.

最后返回cnt给主函数.

N

我的原代吗

#include <stdio.h>

int main()

{

long long a,sum=1,n;

scanf("%lld",&a);

printf("%d ",a);

while(a)

{

n=a;

sum=sum*(n%10);

a=a/10;

if(a==0||sum==0){

 printf("%d ",sum);a=sum;sum=1;}

}

return 0;

}

题解:这数字有点大,我们保险一点所以要用long long类型把a当while循环变量,然后在while循环中将值赋给n,然后在把n的个位数提出来乘,然后在通过除10删掉个位数,如此循环当a=0时我们就输出a然后刷新a为得到的这个新的数字在把sum重新赋值成1。如此反复循环直到sum=0跳出循环结束。

O

我的原代码

#include <stdio.h>

int main()

{

int  n;

char s='%';

float cnt1=0,cnt2=0,cnt3=0,cnt4=0;

scanf("%d",&n);

int a[1005];

for(int i=0;i<n;i++)

{

scanf("%d",&a[i]);

}

for(int i=0;i<n;i++)

{

if(0<=a[i]&&18>=a[i]) cnt1++;

if(19<=a[i]&&35>=a[i]) cnt2++;

if(36<=a[i]&&60>=a[i]) cnt3++;

if(a[i]>=61) cnt4++;

}

float sum=cnt1+cnt2+cnt3+cnt4;

printf("%.2f%%\n",(cnt1/sum)*100);

printf("%.2f%%\n",(cnt2/sum)*100);

printf("%.2f%%\n",(cnt3/sum)*100);

printf("%.2f%%\n",(cnt4/sum)*100);

return 0;

}

题解:就是简单的数学问题,输出百分号就是写双百分号(%%).

P

我的原代码

#include <stdio.h>

int main()

{

int a;

scanf("%d",&a);

printf("%.2lf",1.0*a*a/4);

return 0;

}

题解:一个纯属的数学问题,观察图像用小学学过的割补法,把阴影补过去就可以发现到阴影三角形就是个等腰三角形,半径就它的高最后在直接套公式计算.

Q我的原代码

#include <stdio.h>

int main()

{

int  n,k=0,t;

scanf("%d",&n);

long long a[n];

for(int i=0;i<n;i++)

{

scanf("%lld",&a[i]);

}

for(int i=0;i<n-1;i++)

{

k=i;

  for(int j=i+1;j<n;j++)

{

if(a[k]>a[j])

{

k=j;

}

}

t=a[k];

a[k]=a[i];

a[i]=t;

}

for(int i=0;i<n;i++)

{

printf("%lld\n",a[i]);

}

return 0;

}

题解:一个基础的排序问题,直接使用选择排序会超时,所以要优化一下,减少不必要的交换,

主要就是这个优化.

R 我的原代码

#include <stdio.h>

int main()

{

int n, k=0,t;

scanf("%d",&n);

int a[100005];

for(int i=0;i<n;i++)

{

scanf("%d",&a[i]);

}

for(int i=0;i<n-1;i++)

{

k=i;

for(int j=i+1;j<n;j++)

{

if(a[k]>a[j])

k=j;

}

t=a[i];

a[i]=a[k];

a[k]=t;

}

printf("%d",a[n/2]);

return 0;

}

题解:就是一个很朴素的先排序在直接把中位数找出来的题目.

S我的原代码

#include <stdio.h>

#include <string.h>

int main()

{

char str[70000];

gets(str);

for(int i=0;str[i]!='\0';i++)

{

if(islower(str[i]))

{

str[i]-=32;

}

if(isupper(str[i])) str[i]+=32;

}

puts(str);

return 0;}

题解:根据一个ASCALL码表就可以明白小写比大写多32 ascall值所以小写转大写就是-32大写转小写就是+32,在用一个islower函数和isupper函数判断当前字符是否为大小写。输入字符用gets,scanf遇到空格会自动结束输入。

T我的原代码

#include <stdio.h>

int main()

{

int n,i,j,k,c=1,flage=0;

scanf("%d",&n);

int a[101][101]={0};

for(k=1;k<=n;k++)

{

if(flage==0)

{

j=1;i=k;

while(i!=0)

{

a[i][j]=c;

c++;i--;j++;

}

flage=1;

}

else

{

j=k;i=1;

while(j!=0)

{

a[i][j]=c;

c++;

i++;j--;

}

flage=0;

}

}

for(k=2;k<=n;k++)

{

if(flage==0)

{

i=n;j=k;

while(j!=(n+1))

{

a[i][j]=c;

c++;i--;j++;

}

flage=1;

}

else

{

i=k;j=n;

while(i!=(n+1))

{

a[i][j]=c;

c++;j--;i++;

}

flage=0;

}

}

for(i=1;i<=n;i++)

{

for(j=1;j<=n;j++)

{

printf("%d ",a[i][j]);

}

printf("\n");

}

return 0;

}

题解:

观察例子的每一斜行可以发现是上下上下交替递增,所以可以设置一个flag判断上还是下如果flag=0就向上递增反之向下递增.先从前n斜行下手,然后把每一斜行分成向上和向下2类观察,行号和列号的变化,就可以知道前n斜行的递增类的行号是随着外循环k变化的,然后用一个while给他赋值,一直赋值到行号为0为止。列号同理。n后面几行就也是同样的思路观察行号和列号,给他赋值.

U我的源代码

#include <stdio.h>

int main()

{

long long m,n,a;

scanf("%lld%lld%lld",&m,&n,&a);

long long x,y;

if(m%a==0)

{

x=m/a;

}

else 

{

x=1+(m/a);

}

if(n%a==0)

{

y=n/a;

}

else 

{

y=1+(n/a);

}

printf("%lld",x*y);

return 0;}

题解:从长和宽俩方面考虑竖着要几块地皮横着要几块地皮,如果不能整除就加一

最后相乘得到总的数量.

V

#include <stdio.h>

int main()

{

int n,m,t,a,d,k;

scanf("%d",&t);

for(int i=0;i<t;i++)

 {

scanf("%d%d%d",&n,&m,&d)

if(m>n)

{

k=n;

n=m;

m=k;

}

if(d==0&&n!=m) printf("NO\n");

else 

{

if(n%m==0)

{

a=n/m;

}

else 

{

a=n/m+1;

}

if(a-1>=d) printf("NO\n");

else printf("YES\n");

}

}

return 0;}

题解:直接把黑白棋分成堆数最多的情况,如果这种情况都成立那么其他情况的分法也成立,堆数最多的情况下每一堆的白棋都是一个,黑棋都是a,在判断a-1大于等于d就符合题意了.

W

我的原代码

#include <stdio.h>

int main(){

int t,cnt,k;

char m,s[41],b[41];

scanf("%d",&t);while(t--)

{

 cnt=0;

int n; 

  scanf("%d",&n);

  scanf("%s",s);

  strcpy(b,s);

  for(int j=0;j<n;j++)

  {

   int c=j;

   for( k=j+1;k<n;k++)

   { 

   if(s[c]>s[k])

   {

   c=k;

  }

}

   m=s[c];

   s[c]=s[j];

   s[j]=m;

  }

  for(int j1=0;j1<n;j1++)

  {

   if(b[j1]!=s[j1]) cnt++;

  }

  printf("%d\n",cnt);

}

return 0;}

题解:就是根据ASCALL码值给他排序排完序后在和原数组对照如果不同就计数器cnt++

就欧克啦.

X

我的原代吗

X

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

int comp(const void*p1,const void*p2)

{

const int*a=(const int*)p1;

const int*b=(const int*)p2;

if(*a>*b) return 1;

if(*a==*b) return 0;

return -1;

}

int main()

{

int n,t,m;

int a[200000];

scanf("%d",&t);

while(t--)

{

scanf("%d",&n);

m=2*n;

for(int i=0;i<m;i++)

{

scanf("%d",&a[i]);

}

qsort(a,m,sizeof(int),comp);

for(int i=0;i<m;i++)

{

printf("%d   ",a[i]);

}

printf("\n");

printf("%d\n",a[n+1]-a[n]);

}

return 0;

}

题解:核心思路:这里发现一个数学结论就分班后差距的最小值就是排序完后a[n]-a[n-1]的值,所以要给学生的能力排序这里用选择排序会超时,所以我们用快速排序,排序后在用a[n]-a[n-1]就可以得到最小值了.

Y我的原代码

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int comp(const void*p1,const void*p2)

{

return *(const int*)p2-*(const int*)p1;

}

int main()

{

int n;

scanf("%d",&n);

float m[40],f[40];

char s[6];

int k=0,l=0;

for(int i=0;i<n;i++)

{

float a;

scanf("%s %f",s,&a);

if(s[0]=='m') m[k++]=a;

else f[l++]=a;

 }

 for(int i=0;i<k;i++)

 {

  for(int j=i+1;j<k;j++)

  {

  if(m[i]>m[j])

  {

  float t;

  t=m[i];

  m[i]=m[j];

  m[j]=t;

 }

 }

 }

 qsort(f,l,sizeof(float),comp);

for(int i=0;i<k;i++)

{

printf("%.2f ",m[i]);

}

for(int i=0;i<l;i++)

{

printf("%.2f ",f[i]);

}

return 0;

题解:根据性别来把身高存储在不同的数组里在分别用,给这俩个数组根据题意进行排序然后分别输出就欧克了.

Z#include <stdio.h>

int main(){

int n;

int a[1000],b[1000];

while(scanf("%d",&n)!=EOF)

{

int maxx=0,ans=0;

for(int i=0;i<n;i++)

{

scanf("%d%d",&a[i],&b[i]);

maxx+=b[i]-a[i];

if(maxx>ans) ans=maxx;

}

printf("%d",ans);

}

return 0;}

题解:遍历每个站点的上下车人数,根据实际上车人数计算当前车上乘客数量,若当前需要的座位数大于记录的最少座位数,则更新最少座位数。最后输出最少座位数.

AA

我的原代码

#include <stdio.h>

int main()

{

int n,m,a,b;

scanf("%d%d%d%d",&n,&m,&a,&b);

int cnt=0,sum=0;

if(n%m==0) 

{

cnt=n/m;

sum=cnt*b;

if(n*a<sum)

printf("%d",n*a);

else printf("%d",sum);

}

if(n%m)

{

if(n%m*a<b)

sum=n%m*a+n/m*b;

else sum=(n/m+1)*b;

printf("%d",sum);

 } 

return 0;}

题解:

先用一个判断看看n能否整除m如果可以直接可以计算出最少的花费

如果不可以整除就看余数乘以a看看是否小于特价票,如果小于就是买n/m(取整)张特价票,然后买一张正常票。反之就买n/m(取整)+1张特价票。

最后得出最少的总花费

AB

我的源代码

#include <stdio.h>int main(){

char F[8];

char M[8];

char S[8];

scanf("%s%s%s",F,M,S);

if(F[0]=='r'&&S[0]=='s'&&M[0]=='s'||F[0]=='p'&&S[0]=='r'&&M[0]=='r'||F[0]=='s'&&S[0]=='p'&&M[0]=='p')

printf("F\n");

else 

{if(M[0]=='r'&&F[0]=='s'&&S[0]=='s'||M[0]=='p'&&F[0]=='r'&&S[0]=='r'||M[0]=='s'&&F[0]=='p'&&S[0]=='p')

printf("M\n");

else 

{if(M[0]=='r'&&F[0]=='r'&&S[0]=='p'||M[0]=='p'&&F[0]=='p'&&S[0]=='s'||M[0]=='s'&&F[0]=='s'&&S[0]=='r')

printf("S\n");

else printf("?\n");

}

}

return 0;}

题解:用最朴素的方法每个情况都列举出来判断。

AC我的源代码

#include <stdio.h>int main(){

int a[36]={1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777,8,88,888,8888,9,99,999,9999};

int n,m,cnt;

scanf("%d",&n);

int c[n];

for(int k=0;k<n;k++) scanf("%d",&c[k]);

for(int j=0;j<n;j++)

{

cnt=0;

m=c[j]; 

for(int i=0;i<36;i++)

{

int b=a[i];

while(b)

{

b/=10;

cnt++;

}

if(a[i]==m) break;

}

printf("%d\n",cnt);

}

return 0;

}

题解:把所有的数字存储在数组里,然后根据给的数字,依次遍历数组,然后

通过除10来记录按下的次数,除到0后在进行下一次循环直到找到想要的数字为止,最后输出最终的数字.

AD

我的源代码

#include <stdio.h>int main(){

long long arr[2005];

long long n,d,ans=0,t;

scanf("%lld%lld",&n,&d);

for(int i=1;i<=n;i++)

{

scanf("%lld",&arr[i]);

if(arr[i-1]>=arr[i])

{

t=(arr[i-1]-arr[i])/d+1;

ans+=t;

arr[i]+=t*d;

}

}

printf("%lld",ans);

return 0;}

题解:

这里用到一个贪心思想,追求局部的最优解,就是先实现局部的递增进而实现

整体的递增,就只看n-1和n项元素的关系,我们操作这俩项是后一项始终大于前一项,就用他们的差值去除以d然后加一的这个值t,然后再让第n项加上t*d就实现了局部的递增,然后用ans来记录加了多少次.

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值