2019年5月31日考试总结

        这一次也说不出考的好不好,好嘛,最后一题没有AC(推了两个小时的组合数学,1个小时在对拍,可以说是最有把握的一题)不好嘛,前4道A了,所以也说不出什么,算了,不说了。

        我拿到了试卷,首先,先看了T1,没看出来,我就看了T2,一看我就知道怎么做了,所以我5,6分钟就写好了代码,之后我看了一下T3,发现我会做,但是太麻烦,我就放了放。看了T4,我想这一道题就输出方案占时不会,估计做的时候就会了(因为最近都在写一些要输出方案的DP,不会也得会啊),我去看T5,看了两分钟,我就放弃了。

        然后我去做T3,做到了一半,发现自己好像会做了T1,我就把T3甩开,去做T1,做完了我又去做T3,不一会也就把T3做完了,之后我又去做T4,输出答案后,我又想到怎么输出方案,很快也就写完了。这里总共用时不超过70分钟。

        接下来我就开始我艰苦的历程,首先,我推T4先推了30分钟推出来了一个答案之后,我试了几个数,发现不对,我意识到这有可能要推很久,为了方便,我写了一个对拍,也很快就推好了,然后我又写了60分钟,对拍的程序和我的程序没问题了,我就放在那对拍了1个小时(没有任何错误)之后我就在检查前面的题,做后就是这样的成绩

现在分析一下题目

1.「Codeforces Round #441 Classroom Watch

  (num.pas/c/cpp)

【问题描述】

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

【输入】

共 1 行,一个正整数n 。

 

【输出】

第一行输出一个整数 m,表示有 m 个符合条件的 (若没有符合条件的 ,请只输出一个 0)。
下面m行,每行一个 x ,x按从小到大输出。

 

【输入输出样例1】

num.in

num.out

21

1
15

 

【数据范围】

  

这一题,没有什么理由,就是想到了就完事了,我们发现这里有每个数之和,枚举一下所有数之和,再用n减一下判断是否合法就行了

代码

#include<bits/stdc++.h>
using namespace std;
int U(int x)
{
	int sum=0;
	while(x>0)
	{
		sum+=x%10;
		x/=10;
	}
	return sum;
}
int a[100],tot,n;
int main()
{
	freopen("num.in","r",stdin);
	freopen("num.out","w",stdout); 
    scanf("%d",&n);
    for(int i=0;i<=81;i++)if(U(n-i)==i)a[++tot]=n-i;
	sort(a+1,a+tot+1);
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
	  printf("%d\n",a[i]);
	return 0;
}

组合技能(combo.cpp)

题目描述

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

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

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

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

格式

       输入第一行一个数T,表示T次询问。

       接下来T行,每行三个数A,B,C

       输出T行,每行一个数,表示利润。

范围

       T <= 100

       A,B,C <= 2000

Sample Input 0

3
275 214 420
6 9 11
199 199 255

Sample Output 0

69
4
143

这一题很容易看出来,答案就是A+B-C不用讲

表面积(surface.cpp)

题目描述

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

格式

       输入第一行两个数n,m,接下来n行每行m个数,表示A[i][j]。

       输出一个数,表示表面积。

范围

Sample Input 0

1 1
1

Sample Output 0

6

Sample Input 1

3 3
1 3 4
2 2 3
1 2 4

Sample Output 1

60

这一题是一道模拟题,不难,你只要从一个点的上下左右看就行(前后都是1,不用看)

代码:

#include<bits/stdc++.h>
using namespace std;
int read()
{
	int num=0;bool flag=1;
	char c=getchar();
	for(;c<'0'||c>'9';c=getchar())
      if(c=='-')flag=0;
	for(;c>='0'&&c<='9';c=getchar())
	  num=(num<<1)+(num<<3)+c-'0';
    return flag?num:-num;
}
int n,m,a[110][110];
int main()
{
	freopen("surface.in","r",stdin);
	freopen("surface.out","w",stdout);
	n=read();m=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        a[i][j]=read();
    int sum=2*n*m;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
      {
    	sum=sum+max(0,a[i][j]-a[i-1][j]);
    	sum=sum+max(0,a[i][j]-a[i][j-1]);
    	sum=sum+max(0,a[i][j]-a[i+1][j]);
    	sum=sum+max(0,a[i][j]-a[i][j+1]);
	  }
	cout<<sum;
	return 0;
}

红皇后的旅行(redqueen.cpp)

题目描述

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

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

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

       如果无解,输出Impossible

 

格式

       输入第一行一个数n,第二行四个数,i_start,j_start,i_end,j_end。

       输出第一行一个数,最小步数,第二行输出方案。

范围

      

Sample Input 0

7

6 6 0 1

Sample Output 0

4

UL UL UL L

Sample Input 1

6

5 1 0 5

Sample Output 1

Impossible

Sample Input 2

7

0 3 4 3

Sample Output 2

2

LR LL

 


这一道毫无疑问,是一道BFS,没问题对吧,主要是一个方案输出,但是经过了这么多次的练习,方案输出都已经不是问题了,只要我们用一个v[xx][yy](pair或者结构体)来储存一下这一状态是从那一状态转移过来的就行了,之后再dfs从尾查找就行。

代码:

#include<bits/stdc++.h>
using namespace std;
struct cow{int x,y;};
queue<cow>q;int n,d[210][210];cow st,ed,v[210][210];
int dx[6]={-2,-2,+0,+2,+2,+0},dy[6]={-1,+1,+2,+1,-1,-2};
string D[6]={"UL","UR","R","LR","LL","L"};
void BFS()
{
	memset(d,-1,sizeof(d));
	memset(v,-1,sizeof(v));
	while(!q.empty())q.pop();
	q.push(st);d[st.x][st.y]=0;
	while(!q.empty())
	{
		cow now=q.front();q.pop();
		for(int i=0;i<6;i++)
		{
			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;
			q.push(cow{xx,yy});
			d[xx][yy]=d[now.x][now.y]+1;
			v[xx][yy].x=now.x;v[xx][yy].y=now.y;
			if(xx==ed.x&&yy==ed.y)return ;
		}
	}
	cout<<"Impossible";exit(0);
}
void dfs(cow 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,&st.x,&st.y,&ed.x,&ed.y);
	BFS();printf("%d\n",d[ed.x][ed.y]);dfs(ed);
	return 0;
}

构造序列(construct.cpp)

题目描述

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

       答案对10^9+7取模。

格式

       输入共一行,包含三个数,n,k,x。

       输出一个数,表示答案。

范围

      

Sample Input 1

4 3 2

Sample Output 1

3

这道题我一看:一定要用快速幂!然后我之后就没有想到正解,真的很崩溃。现在来说一下正解

先考虑如果没有A[1]A[n]的限制,怎么办?答案就是k*(k-1)^(n-1)

如果只有A[1]的限制?答案就是(k-1)^(n-1)

这样我们就可以知道一个很神奇的正解:

f[i]表示i这个位置为x是的方案数

f[i]=(k-1)^(i-2)-f[i-1]     最后输出f[n]即可

代码:

#include<bits/stdc++.h>
using namespace std;
#define Mod 1000000007
#define ll long long
ll pow(ll x,ll y)
{
	if(y==0)return 0;
	ll sum=pow(x,y/2);
	sum=(sum*2)%Mod;
	if(y&1)return (sum+x)%Mod;
	return sum;
}
ll power(ll x,ll y)
{
	if(y==0)return 1;
	ll sum=power(x,y/2)%Mod;
	if(y&1)return pow(pow(sum,sum),x)%Mod;
	return pow(sum,sum)%Mod;
}
int f[100010];
int main()
{
	freopen("construct.in","r",stdin);
	freopen("construct.out","w",stdout);
    int n,k,x;cin>>n>>k>>x;
    if(x==1)f[2]=0;else f[2]=1;
	for(int i=3;i<=n;i++)
	  f[i]=(power(k-1,i-2)-f[i-1]+Mod)%Mod;
	cout<<f[n];
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值