5.31考试总结

暂时只写了每题的题解,有待补充

1.「Codeforces Round #441 Classroom Watch

【问题描述】

给出一个正整数 n,现在问存在多少个 x,使得  x在十进制下的每一位之和加上 x 等于 n。

这题拿到时就想,如果n是两位数,那么x基本上也得是两位数了,然后就觉得对于每个n的x都应有一个范围,再一想,各位数之和最多81,那么就n-81到n都试一试就好了

#include<bits/stdc++.h>
using namespace std;
int x,m=0,k,ans[10000],t,s;
int main()
{
	freopen("num.in","r",stdin);
	freopen("num.out","w",stdout);
	scanf("%d",&x);
	if(x>81)k=x-81;
	 else k=1;
	for(int i=k;i<=x;i++)
	{
		t=i,s=i;
		while(t>0)
	    {
	   	    s+=t%10;
	   	    t/=10;
	   	    if(t==0&&s==x)ans[++m]=i;
	    }
	}
	if(m!=0){
	  printf("%d\n",m);
	  for(int i=1;i<=m;i++)
	    printf("%d\n",ans[i]);
	}
	else printf("%d\n",0);
	return 0;
}

2、组合技能

蓝月商城出新技能书了!!

       如果古天乐想购买“旋风斩”,则他需要花费A元;如果古天乐想买“半月弯刀”,则需要B元;如果古天乐两个一起买,则需要C元。

       蓝月的设计师非常有头脑,每样商品的利润都是相同的。即假设旋风斩和半月弯刀的成本为a,b元,则A-a=B-b=C-a-b。

       给出A,B,C求出利润,数据保证为正数。

已在代码中写了如何推导

#include<bits/stdc++.h>
using namespace std;
int T,A,B,C;
/*
    A-a=C-a-b
      b=C-A
    B-b=B-C+A
*/
int main()
{
	freopen("combo.in","r",stdin);
	freopen("combo.out","w",stdout);
	scanf("%d",&T);
	for(int i=1;i<=T;i++)
	{
		scanf("%d%d%d",&A,&B,&C);
		printf("%d\n",B-C+A);
	}
	return 0;
}

3表面积

古天乐在搭积木,积木图可以抽象为一个n*m的网格图,其中第(i,j)的位置有A[i][j]个积木。求表面积。

这题得注意凹在里面的也算表面积

不过可以算出总面积和重叠的面积,再相减,思路在注释中已注明

#include<bits/stdc++.h>
using namespace std;
int n,m,sum1=0,sum2,a[110][110]={};
int main()
{
	freopen("surface.in","r",stdin);
	freopen("surface.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
	 {
	 	scanf("%d",&a[i][j]);
	 	sum1+=a[i][j];
	 	//对于每一个位置,计算上面,左边,以及自己的重叠
		 //因为 是从左上枚举到右下,所以每次把左边上面的算出就好了 
	 	sum2+=min(a[i][j],a[i-1][j])+min(a[i][j],a[i][j-1])+(a[i][j]-1);
	 	//           自己或左边         上面或自己       每一格有(a[i][j]-1)个重叠位置              
	 }
	printf("%d\n",sum1*6-sum2*2);
	return 0;
}

4红皇后的旅行

给定一个n*n的棋盘,行和列标号为0,1,2,….,n-1。在棋盘的(i_start,j_start)位置上有一位红皇后,每次红皇后可以往六个方向走,如图所示:

       现在红皇后想去(i_end,j_end)点,求最短距离,并且输出一条路径。

       显然最短路径有无穷条,请按照以下顺序来搜索:UL, UR, R, LR, LL, L

       如果无解,输出Impossible

这题就先用BFS求出最短路,并记录每格的上一格,再用DFS求出路径

#include<bits/stdc++.h>
using namespace std;
int n,d[210][210];
struct K{int x,y;};
K start,end,v[210][210];
queue<K>q;
string D[6]={"UL","UR","R","LR","LL","L"};
int dx[6]={-2,-2,0,2,2,0},dy[6]={-1,1,2,1,-1,-2};
/*
d[i][j]表示走到(i,j)的最小距离
v[i][j]表示走到(i,j)的上一个位置 
*/ 
void BFS()
{
	memset(d,-1,sizeof(d));
	memset(v,-1,sizeof(v));
	while(!q.empty())q.pop();
	q.push(start);
	d[start.x][start.y]=0;
	while(!q.empty())
	{
		K now=q.front();
		q.pop();
		for(int i=0;i<6;i++)//向六个方向走 
		{
		    K k;
			int xx=now.x+dx[i],yy=now.y+dy[i];//新的位置 
			if(d[xx][yy]!=-1||xx<0||xx>n||yy<0||yy>n)//位置越界或者已走到 
			  continue;
		    k.x=xx,k.y=yy;
		    q.push(k);
			d[xx][yy]=d[now.x][now.y]+1;
			v[xx][yy].x=now.x,v[xx][yy].y=now.y;
			if(xx==end.x&&yy==end.y)return;
		}
	}
	cout<<"Impossible"<<endl;
	exit(0);
}
void DFS(K now)
{
	int xx=now.x,yy=now.y;
	int xb=v[now.x][now.y].x;
	int yb=v[now.x][now.y].y;
	if(xb==-1&&yb==-1)return ;
	DFS(v[now.x][now.y]);
	for(int i=0;i<6;i++)
	  if(xb+dx[i]==xx&&yb+dy[i]==yy)
	  {
	  	cout<<D[i]<<' ';
	  	break;
	  }
}
int main()
{
	freopen("redqueen.in","r",stdin);
	freopen("redqueen.out","w",stdout);
	scanf("%d%d%d%d%d",&n,&start.x,&start.y,&end.x,&end.y);
	BFS();
	printf("%d\n",d[end.x][end.y]);
	DFS(end);
	return 0; 
}

5构造序列

有一个长度为n的序列A,其中A[1]=1,A[n]=x,A[2…n-1]可以是1至k间任意一个正整数。求有多少个不同的序列,使得相邻两个数不同。

       答案对10^9+7取模。

#include<bits/stdc++.h>
using namespace std;
const long long mod=1000000007;
long long n,k,x,f[100100],fx[100100];
int main()
{
	freopen("construct.in","r",stdin);
	freopen("construct.out","w",stdout); 
	scanf("%d%d%d",&n,&k,&x);
	f[2]=k-1;
	for(int i=3;i<n;i++)
	 f[i]=(f[i-1]*(k-1))%mod;
	if(x==1)fx[2]=0;
	 else fx[2]=1;
	for(int i=3;i<=n;i++)
	 fx[i]=(f[i-1]-fx[i-1]+mod)%mod;
	cout<<fx[n]<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值