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;
}
一道略金典的题目
就是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;
}
数的拆分问题
#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;
}