题解_四月十九

(1)police:按照题目意思,如果有小偷没警察那小偷就直接跑了,有警察那就抓住警察人数那么多的小偷,有剩余小偷就跑了,有剩余警察就保留。只要在适当的时候初始注意初始警察和小偷人数。

#include<stdio.h>
int main()
{
	int i,n,t,sum,k;
	while(scanf("%d",&t)==1)
	{
		sum=0;k=0;
		for(i=1;i<=t;i++)
		{
			scanf("%d",&n);
			sum+=n;
			if(sum<0){k+=sum;sum=0;}
		}
		printf("%d\n",-k);
	}
	return 0;
}

(2)蛋的阶乘:观察会发现只有5乘以偶数的时候会产生0,而偶数的个数远远多余5个个数,因此其实此题就是计算有多少个5或者5的倍数。

#include<stdio.h>
int main()
{
	int i,t,k;
	while(scanf("%d",&t)==1)
	{
		i=5;k=0;
		while(t>=i)
		{
			k+=t/i;
			i*=5;
		}
		printf("%d\n",k);
	}
	return 0;
}


(3)追牛:模拟提+字符串的处理,只需要模拟出牛和人走动的方向和是否转向,人和牛走动的方向有四个,用四个数字即可记录,地图上除了空地就是不可以走的,为了不超出可以走的边界,可以在最外圈模拟放上一圈栅栏。第一次提交时间超限,原因是没有判断出追不到牛的情况,后来为了方便直接把追得步数大于一万的定义为追不到。

#include<stdio.h>
#include<string.h>
int main()
{
	int i1,i2,j1,j2,i,x[12][12]={0},k=1,m=0,n=0,sum=0;
	char c[12];
	for(i=0;i<=11;i++)
		x[i][0]=x[0][i]=x[11][i]=x[i][11]=1;
	while(scanf("%s",c)==1&&strlen(c)>5)
	{
		for(i=0;i<10;i++)
		{
			if(c[i]=='*')x[k][i+1]=1;
			else if(c[i]=='C'){x[k][i+1]=0;i1=k;i2=i+1;}
			else if(c[i]=='F'){x[k][i+1]=0;j1=k;j2=i+1;}
		}
		k++;
		if(k==11){
			while(i1!=j1||i2!=j2)
			{
				if(m==0)if(x[i1-1][i2]==1)m=1;else i1--;
				else if(m==1)if(x[i1][i2+1]==1)m=2;else i2++;
				else if(m==2)if(x[i1+1][i2]==1)m=3;else i1++;
				else if(m==3)if(x[i1][i2-1]==1)m=0;else i2--;
				if(n==0)if(x[j1-1][j2]==1)n=1;else j1--;
				else if(n==1)if(x[j1][j2+1]==1)n=2;else j2++;
				else if(n==2)if(x[j1+1][j2]==1)n=3;else j1++;
				else if(n==3)if(x[j1][j2-1]==1)n=0;else j2--;
				sum++;
				if(sum>10000)break;
			}
			if(sum<10000)printf("%d\n",sum);else printf("0\n");
			memset(x,0,sizeof(x));k=1;m=0;n=0;
			for(i=0;i<=11;i++)
				x[i][0]=x[0][i]=x[11][i]=x[i][11]=1;
			sum=0;
		}
	}
	return 1;
}


(4)放苹果:此题看似简单,但其实很难,以前数学书上学过类似的排列组合(很多条路也用到组合排列,但是题目上说路径只能走一次而非城市只能走一次,导致我想复杂了),可以知道F[m][n]=F[m][n-1]+F[m-n][n],F[m][n]表示把m个苹果放在n个盘子里,可以看成把m个苹果放在[n-1]个盘子里的方法数在加上从每个盘子里拿出一个放到最后一个空盘子里的方法数,

#include<stdio.h>
int ha(int m,int n)
{
	if(n==0)return 0;
	if(n==1)return 1;
	if(m<0)return 0;
	return ha(m,n-1)+ha(m-n,n);
}
int main()
{
	int m,n,i;
	while(scanf("%d",&i)==1)
		for(;i;i--)
		{
			scanf("%d%d",&m,&n);
			printf("%d\n",ha(m,n));
		}
	return 1;
}


(5)ISBN码:字符串处理,只要能在字符串中读出需要的信息就没有什么难的了,最后就只需要判断最后的验证码是否正确,正确输出right,不正确输出原来的字符串减去错误的验证码加上正确的验证码,

#include<stdio.h>
int main()
{
	int i1,i2,i3,sum,t;
	char x;
	while(scanf("%d-%d-%d-%c",&i1,&i2,&i3,&x)==4)
	{
		sum=0;
		sum+=i1+2*(i2/100)+3*(i2/10%10)+4*(i2%10);
		sum+=5*(i3/10000)+6*(i3/1000%10)+7*(i3/100%10)+8*(i3/10%10)+9*(i3%10);
		if(x=='X')t=10;else t=x-'0';
		if(sum%11==t)printf("Right\n");
		else 
		if(sum%11<10)printf("%d-%d-%d-%d\n",i1,i2,i3,sum%11);
		else printf("%d-%d-%d-X\n",i1,i2,i3);
	}
	return 0;
}


(6)过河卒:因为每个位置都只能向右或者向下走,所以容易观察得到每个位置只能由上或者左方向走到(遇到马的控制点的时候把那点的走法归为0即可),因此有递归方程F[x][y]=F[x-1][y]+F[x][y-1],但是用这个递归方程太耗时了,建议从第一个位置开始递推而不用递归,代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
	int m,n,x,y,i,j,c[21][21];
	while(scanf("%d%d%d%d",&x,&y,&m,&n)==4)
	{
		memset(c,0,sizeof(c));
		c[m][n]=-1;
		c[0][0]=1;
		if(m>=2&&n>=1)c[m-2][n-1]=-1;
		if(m>=1&&n>=2)c[m-1][n-2]=-1;
		if(y-n>=2&&x-m>=1)c[m+1][n+2]=-1;
		if(y-n>=1&&x-m>=2)c[m+2][n+1]=-1;
		if(m>=2&&y-n>=1)c[m-2][n+1]=-1;
		if(m>=1&&y-n>=1)c[m-1][n+2]=-1;
		if(x-m>=1&&n>=2)c[m+1][n-2]=-1;
		if(x-m>=2&&n>=1)c[m+2][n-1]=-1;
		for(i=1;i<=x;i++)
			if(c[i][0]!=-1)c[i][0]=1;
			else break;
		for(j=1;j<=y;j++)
			if(c[0][j]!=-1)c[0][j]=1;
			else break;
		for(i=1;i<=x;i++)
			for(j=1;j<=y;j++)
				if(c[i][j]!=-1&&c[i][j-1]!=-1&&c[i-1][j]!=-1)
					c[i][j]=c[i][j-1]+c[i-1][j];
				else
				{
					if(c[i][j]!=-1&&c[i][j-1]!=-1)
						c[i][j]=c[i][j-1];
					if(c[i][j]!=-1&&c[i-1][j]!=-1)
						c[i][j]=c[i-1][j];
				}
		printf("%d\n",c[x][y]);
	}
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值