18/10/19 周五集训队测试赛补题题解

A.成绩

签到题不多说注意用double就行

代码

#include <iostream>
using namespace std;
main()
{
	double a,b,c;
	cin>>a>>b>>c;
	double d=a*0.2+b*0.3+c*0.5;
	printf("%.0lf",d);
}

B.棋盘

DFS+剪枝,特别的地方在于魔法的使用,因为DFS的特殊性,魔法用bool表示的上一个格子是不是已经使用了魔法

代码

#include <bits/stdc++.h>
using namespace std;
int f[110][110];
int mp[110][110];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int inf=INT_MAX;
int m,n,ans=inf;
void dfs(int x,int y,int sum,bool magic)
{
	if(x<1||y<1||x>m||y>m)//判断边界 
	return;
	if(!mp[x][y])//判断是否有颜色,只能站在有颜色的格子上 
	return;
	if(sum>=f[x][y])//判断记忆数组,如果总和大于记忆数组,那么剪枝 
	return;
	f[x][y]=sum;
	if(x==m&&y==m)//正常的结束 
	{
		if(sum<ans)
		ans=sum;
		return;
	}
	for(int i=0;i<4;i++)//四向dfs的套路写法 
	{
		int xx=x+dx[i];
		int yy=y+dy[i];
		if(mp[xx][yy])//如果格子有颜色 
		{
			if(mp[xx][yy]==mp[x][y])//相等不用花费金币,否则花费一个金币 
			dfs(xx,yy,sum,false);
			else
			dfs(xx,yy,sum+1,false);
		}
		else if(!mp[xx][yy]&&!magic)//如果格子没有颜色且还能用魔法(上一格没有用魔法) 
		{
			mp[xx][yy]=mp[x][y];
			dfs(xx,yy,sum+2,true);
			mp[xx][yy]=0;
		}
	}
}
main()
{
	memset(f,0x7f,sizeof(f));//这里0x7f代表127,代表着把二维数组f都初始化为极大值仅仅比INT_MAX小一点点
	cin>>m>>n;
	while(n--)
	{
		int x,y,c;
		cin>>x>>y>>c;
		mp[x][y]=c+1;	
	}	
	dfs(1,1,0,false);
	if(ans==inf)
	cout<<-1;
	else
	cout<<ans;
}	

C.跳房子(待研究)

D.列队(待研究)

E.小凯的疑惑

不多说了真的是反向筛选题,你想的越多这个题你就有可能陷入奇怪的境地

至于公式的证明方法的简略说法(伪证命)

因为要拿两个硬币,且两个硬币互质,那么如果每个硬币都拿一个的话就是能购买ab的物品。此时可以拿b个a也可以拿a个b也可以一样都不拿所以就是ab-a-b(伪证明)

代码

#include <bits/stdc++.h>
using namespace std;
main()
{
    long long a,b;
    cin>>a>>b;
    cout<<a*b-a-b;
}

F.时间复杂度(待研究)

G.图书管理员

这个题可算比较简单一些了,也是我唯一比赛中除了签到题做出来的题。直接用string输入数据转换成整型升序排序,然后把每个要比较的数进行比较即可。

代码

#include <bits/stdc++.h>
using namespace std;
string st1[1110];
string st2[1110];
bool cmp(string a,string b)//排序的规则函数,直接把输入的string转换成int排序,因为string的字典序对于这种常数的排序来说并不是升序的
{
	stringstream s1,s2;
	s1<<a;int c;
	s1>>c;
	s2<<b;int d;
	s2>>d;
	return c<d;
}
main()
{
	int n,q;
	cin>>n>>q;
	for(int i=0;i<n;i++)
	cin>>st1[i];
	for(int i=0;i<q;i++)
	{
		int k;
		cin>>k>>st2[i];
	}
	sort(st1,st1+n,cmp);
	for(int k=0;k<q;k++)//每一个情况的枚举
	{
		int f;//判断用的变量
		for(int i=0;i<n;i++)//把原来的图书编号一一的与要查询的编号进行比较
		{
			f=1;
			for(int j=1;j<=min(st1[i].size(),st2[k].size());j++)//比较的规则
			{
				if(st1[i].size()-(st2[k].size()+1)+j<0)//如果比较过程中出现了负数的数组下标,为了防止RE直接break,进行下一个图书编号的比较
				break;
				if(st1[i][st1[i].size()-(st2[k].size()+1)+j]!=st2[k][j-1])//方法自己手算一下就行这里进行比较
				{
					f=0;
					break;
				}
			}
			if(f)//如果发现比较成功直接输出然后break
			{
				cout<<st1[i]<<endl;
				break;
			}
		}		
		if(!f)//如果一趟下来没有比较成功的输出-1
		cout<<"-1
";
	}
}
原文地址:https://www.cnblogs.com/baccano-acmer/p/9821125.html