2014_4_19

题目地址

1.好多条路

这个题目,嗯,动态规划

d[i]:=表示之间最多有i个城市的走法

那么就分成是否直达了,直达就只有1种走法,如果不直达,就先选取一个城市,就变成最多含有i-1个城市的方法了

d[i]=d[i-1]*i+1

#include <bits/stdc++.h>
using namespace std;

#define maxn 500000
#define MOD 100000007
long long d[maxn+5];

int main()
{
	int n;
	memset(d,0,sizeof(d));
	d[0]=1;
	for (long long i=1;i<=maxn;i++){
		d[i]=((d[i-1]*i)%MOD+1)%MOD;
	}	
	
	while(~scanf("%d",&n)){
		printf("%lld\n",d[n-2]);
	}
	return 0;
}

2.过河卒

还是dp问题 d[i][j]=d[i-1][j]+d[i][j-1],注意下边界问题就是了

#include <bits/stdc++.h>
using namespace std;
int a[25][25];
int d[25][25];
int main()
{
	//freopen("F:\\TestFiles\\test.in","r",stdin);
	//freopen("F:\\TestFiles\\test2.out","w",stdout);
	int x1,y1,x2,y2;
	while(~scanf("%d%d%d%d",&x1,&y1,&x2,&y2)){
		memset(a,0,sizeof(a));
		memset(d,0,sizeof(d));
		d[0][0]=1;
		
		int w[7]={-2,-1,1,2};
		
		a[x2][y2]=1;
		for (int i=0;i<4;i++){
			for (int j=0;j<4;j++){
				
				if (fabs(w[i])==fabs(w[j])) continue;
				
				int xx=x2+w[i];
				int yy=y2+w[j];
				if (xx>=0&&yy>=0) a[xx][yy]=1;
			}
		}
		
		
		for (int i=0;i<=x1;i++){
			for (int j=0;j<=y1;j++){
					
				if (a[i][j]==1){
					d[i][j]=0;
					continue;
				}
					
				if (i-1>=0&&a[i-1][j]==0) d[i][j]+=d[i-1][j];
				if (j-1>=0&&a[i][j-1]==0) d[i][j]+=d[i][j-1];
			}
		}
	
		
		
		printf("%d\n",d[x1][y1]);
		
	}
	return 0;
}

C.模拟题嘛,算出来比较下就ok了

#include <bits/stdc++.h>
using namespace std;
int main()
{
	//freopen("F:\\TestFiles\\test.in","r",stdin);
	//freopen("F:\\TestFiles\\test2.out","w",stdout);
	char as[20];
	while(gets(as)!=NULL){
		int ans=0;
		int num=1;
		for (int i=0;i<12;i++){
			if (as[i]=='-') continue;
			ans+=(as[i]-'0')*num;
			num++;
		}
		
		int ans2=0;
		if (as[12]=='X') ans2=10;
		else ans2=as[12]-'0';
		
		ans=ans%11;
		ans2=ans2%11;
		
		if (ans2==ans) printf("Right\n");
		else {
			for (int i=0;i<12;i++){
				printf("%c",as[i]);
			}
			
			if (ans<10) printf("%d\n",ans);
			else printf("X\n");
		}
		
	}
	return 0;
}

D.police

看到这题。。嗯,一个一个的数过去,,遇到能抵消的就加一,不能抵消的就跳过

#include <bits/stdc++.h>
using namespace std;
int main()
{
	//freopen("F:\\TestFiles\\test.in","r",stdin);
	//freopen("F:\\TestFiles\\test2.out","w",stdout);
	int n;
	while(~scanf("%d",&n)){
		int sum=0;
		int pp=0;
		for (int i=0;i<n;i++){
			int data;
			scanf("%d",&data);
			pp+=data;
			if (pp>=0) continue;
			sum+=pp;
			pp=0;
		}
		
		printf("%d\n",-sum);
		
	}
	return 0;
}


E.蛋的阶乘

一道略金典的题目

就是0和5的个数有关,因为偶数的个数太多了
所以就记录下5的个数与5的倍数的个数即可

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	while(~scanf("%d",&n)){
		int sum=0;
		for (long long i=5;i<=n;i=i*5){
			sum+=n/i;
		}
		printf("%d\n",sum);
	}
	return 0;
}


F.镜像

这题,去建立一颗树,并不明智,,首先我觉得建立一棵树就不好建立

直接打印即可,按照后序打印

#include <bits/stdc++.h>
using namespace std;

int kkk=0;

void print(char as[],int len)
{
	int i=1;
	
	if (kkk) printf(" ");
	else kkk=1;
	
	while(i<len-1){
		if (as[i]!='('&&as[i]!=')') printf("%c",as[i++]);
		else break;
	}

	char ad[305];
	char ak[305];
	int lend=0,lenk=0;
	
	int g=0;
	
	while(i<len-1){
		ad[lend++]=as[i];
		if (as[i]=='(') g++;
		if (as[i]==')') g--;
		i++;
		if (g==0) break;
	}
	ad[lend]='\0';
	g=0;
	
	while(i<len-1){
		ak[lenk++]=as[i];
		if (as[i]=='(') g++;
		if (as[i]==')') g--;
		i++;
		if (g==0) break;	
	}
	ak[lenk]='\0';
	
	if (lenk>0) print(ak,lenk);
	
	if (lend>0) print(ad,lend);
	
}

int main()
{
	//freopen("F:\\TestFiles\\test.in","r",stdin);
	//freopen("F:\\TestFiles\\test.out","w",stdout);
	char a[305];
	while(~scanf("%s",a)){
		kkk=0;
		int len=strlen(a);
		print(a,len);
		printf("\n");
	}
	return 0;
}


G。没啥好说的了,详细见代码,看了就立马明白了==

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int aa[7]={0};
char* a[4][10];
char b[7]={'I','V','X','L','C','D','M'};
void doo(int as)
{
	int an=0;
	int n=0;
	while(as!=0)
	{
		if (as%10!=0)
		{
			for (int i=0;i<strlen(a[n][as%10]);i++)
			switch (a[n][as%10][i])
			{
			case 'I':{aa[0]++;break;}
			case 'V':{aa[1]++;break;}
			case 'X':{aa[2]++;break;}
			case 'L':{aa[3]++;break;}
			case 'C':{aa[4]++;break;}
			case 'D':{aa[5]++;break;}
			case 'M':{aa[6]++;break;}
			}
		}
		as=as/10;
		n++;
	}
}
int main()
{
	//freopen("F:\\TestFiles\\test1.in","r",stdin);
	//freopen("F:\\TestFiles\\test3.out","w",stdout);
	a[0][1]="I";a[0][2]="II";a[0][3]="III";a[0][4]="IV";a[0][5]="V";a[0][6]="VI";a[0][7]="VII";a[0][8]="VIII";a[0][9]="IX";
	a[1][1]="X";a[1][2]="XX";a[1][3]="XXX";a[1][4]="XL";a[1][5]="L";a[1][6]="LX";a[1][7]="LXX";a[1][8]="LXXX";a[1][9]="XC";
	a[2][1]="C";a[2][2]="CC";a[2][3]="CCC";a[2][4]="CD";a[2][5]="D";a[2][6]="DC";a[2][7]="DCC";a[2][8]="DCCC";a[2][9]="CM";
	a[3][1]="M";a[3][2]="MM";a[3][3]="MMM";
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		memset(aa,0,sizeof(aa));
		for (int i=1;i<=n;i++)
			doo(i);
		for (int i=0;i<7;i++)
			if (aa[i]) printf("%c %d\n",b[i],aa[i]);
	}
	return 0;
}

H.找牛

首先因为无论是牛还是人走的路的状态只和你出发的时候的状态有关

人有4*10*10种,牛也有4*10*10种,所以最多16w种状态

所以如果移动了16w次后就没有必要移动了

#include<stdio.h>
struct node
{
	int x,y;
	int move;
};
char a[10][10];
void move(node& animal)
{
	switch (animal.move)
	{
	case 0:
		{
			if (animal.x==0||a[animal.x-1][animal.y]=='*')
				animal.move=(animal.move+1)%4;
			else animal.x--;
			break;
		}
		case 1:
		{
			if (animal.y==9||a[animal.x][animal.y+1]=='*')
				animal.move=(animal.move+1)%4;
			else animal.y++;
			break;
		}
		case 2:
		{
			if (animal.x==9||a[animal.x+1][animal.y]=='*')
				animal.move=(animal.move+1)%4;
			else animal.x++;
			break;
		}
		case 3:
		{
			if (animal.y==0||a[animal.x][animal.y-1]=='*')
				animal.move=(animal.move+1)%4;
			else animal.y--;
			break;
		}
	}
}
int main()
{
	while(scanf("%s",a[0])!=EOF)
	{
		for (int i=1;i<10;i++) scanf("%s",a[i]);
		node people,niu;
		int x,y,x1,y1;
		for (int i=0;i<10;i++)
			for (int j=0;j<10;j++)
			{
				if (a[i][j]=='C') {x=niu.x=i;y=niu.y=j;niu.move=0;}
				if (a[i][j]=='F') {x1=people.x=i;y1=people.y=j;people.move=0;}
			}
			int all=0;
			int ok=0;
			while(niu.x!=people.x||niu.y!=people.y)
			{
				all++;
				move(niu);
				move(people);
				if (all>=160000) {printf("0\n");ok=1;break;}
			}
			if (!ok)
			printf("%d\n",all);
	}
	return 0;
}




I.放苹果

数的拆分问题

#include <bits/stdc++.h>
using namespace std;
int main()
{
	
	//freopen("F:\\TestFiles\\test.in","r",stdin);
	//freopen("F:\\TestFiles\\test2.out","w",stdout);
	int d[105][105];
	memset(d,0,sizeof(d));
	
	for(int j=0;j<=100;j++){
		d[0][j]=1;
		d[1][j]=1;
	}
	
	for (int i=2;i<=100;i++){
		for (int j=1;j<=100;j++){
			if (j>i) d[i][j]=d[i][i];
			else d[i][j]=d[i][j-1]+d[i-j][j];
		}
	}
	
	
	int t;
	while(~scanf("%d",&t)){
		while(t--){
			int n,m;
			scanf("%d%d",&n,&m);
			printf("%d\n",d[n][m]);
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值