首页 > 其他分享 >Test 2022.09.27

Test 2022.09.27

时间:2022-09-27 21:59:17浏览次数:74  
标签:27 int x1 y1 include 2022.09 Test calc dis

今天不知道是什么专场了,但是我知道的是我今天真的没有改完!!!!太气了,最短路的赋值号写成大于竟然不会报错,害得我改了半个下午一个晚上,lz快要崩溃了

T1 Windy数

简简单单数位dp,但是我一测的时候好像打了一个bug,不知道在哪,wa掉了一个点,后面交了一遍之前的代码,就过了,思路就是定义\(dp[i][j]\)为长度为\(i\)位的数,且最高位是\(j\)的满足条件的数的数量,转移方程懒得写\(LaTeX\)的大括号了,今天实在是时间不够了,就直接上代码

点击查看代码
void pre()
{
	for(int i=0;i<=9;i++)
		dp[1][i]=1;	
	for(int i=2;i<=10;i++)
	{
		for(int j=0;j<=9;j++)
		{
			for(int k=0;k<=9;k++)
			{
				if(abs(j-k)>=2)	dp[i][j]+=dp[i-1][k]; 
			}
		}
	}//dp[i][j]只会在前面有数并要拼上去时才会用到,因为计算时考虑了前导0对后面的影响 
}

然后数位\(dp\)统计答案一直都是一个难点,注释都在代码里面了

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
bool check(int x,int y)
{
	return abs(x-y)>=2?1:0;
}
int dp[15][15];int a[15];int d,t;int s[15];
void pre()
{
	for(int i=0;i<=9;i++)
		dp[1][i]=1;	
	for(int i=2;i<=10;i++)
	{
		for(int j=0;j<=9;j++)
		{
			for(int k=0;k<=9;k++)
			{
				if(abs(j-k)>=2)	dp[i][j]+=dp[i-1][k]; 
			}
		}
	}//dp[i][j]只会在前面有数并要拼上去时才会用到,因为计算时考虑了前导0对后面的影响 
}
long long calc(int x)
{	
	memset(a,0,sizeof a);
	
	int cnt=0;long long ans=0;
	do
	{
		a[++cnt]=x%10;
		x/=10;
	}while(x);
	
	for(int i=1;i<=cnt-1;i++)
	{
		for(int j=1;j<=9;j++)
			ans+=dp[i][j]; 
	}//所有位数不足cnt的情况 
	
	for(int i=1;i<a[cnt];i++)
		ans+=dp[cnt][i];
	//位数为cnt但是最高位小于a【cnt】的情况
	
	
	for(int i=cnt-1;i>=1;i--)
	{
		if(i==1&&check(a[i],a[i+1]))
			ans++;
		for(int j=0;j<a[i];j++)
		{
			if (check(j,a[i+1]))
				ans+=dp[i][j];
		}
		if(!check(a[i],a[i+1]))break;/*当前不满足后面就不可能*/
	}
	 
	
	return ans;
}

int main()
{
	scanf("%d%d",&d,&t);
	pre();
//	for(int i=0;i<=50;i++)
//	{
//		printf("calc(%d):%d\n",i,calc(i));
//	}
//	for(int i=1;i<=3;i++)
//	{
//		for(int j=0;j<=9;j++)
//		printf("dp[%d][%d]:%d\n",i,j,dp[i][j]);
//	}
//	printf("%d\n",calc(t));
	printf("%lld",calc(t)-calc(d-1));
	return 0;
}

T2 生日快乐

本来以为是个结论题,于是自己乱整了几组数据,发现要尽量分的平均,于是就有了以下代码

点击查看代码
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
void swap1(double &x,double &y){double tmp=x;x=y;y=tmp;}
int main()
{
	double x,y,n;
	scanf("%lf%lf%lf",&x,&y,&n);
	double ans1=-1,ans2=-1;
	int div1=(int)n/2,div2=(int)n-div1;
	double tmp1=1.0*div1/(div1+div2)*x,tmp2=y/(1.0*div1);
	if(tmp1<tmp2)swap1(tmp1,tmp2);
	ans1=max(ans1,tmp1/tmp2);
	
	tmp1=1.0*div2/(div1+div2)*x,tmp2=y/(1.0*div2);
	if(tmp1<tmp2)swap1(tmp1,tmp2);
	ans1=max(ans1,tmp1/tmp2);	
	////////////////
	tmp1=1.0*div1/(div1+div2)*y,tmp2=x/(1.0*div1);
	if(tmp1<tmp2)swap1(tmp1,tmp2);
	ans2=max(ans2,tmp1/tmp2);
	
	tmp1=1.0*div2/(div1+div2)*y,tmp2=x/(1.0*div2);
	if(tmp1<tmp2)swap1(tmp1,tmp2);
	ans2=max(ans2,tmp1/tmp2);
	
	printf("%.6lf",min(ans1,ans2));
	return 0;
}

然而事实证明这样的做法是错误的,正确答案是搜索 先贴代码才好讲
点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
double dfs(double x,double y,double n)
{
	if(n==1)return 1.0*max(x,y)/min(x,y);
	double tmp=1145141919;double divide_x=x*1.0/n,divide_y=y*1.0/n;
	for(int i=1;i<=n/2;i++)
	{
		tmp=min(tmp,max(dfs(divide_x*i,y,i),dfs(x-divide_x*i,y,n-i)));
		tmp=min(tmp,max(dfs(x,divide_y*i,i),dfs(x,y-divide_y*i,n-i)));
	}
	return tmp;
}
int main()
{
//	freopen("happy.in","r",stdin);
//	freopen("happy.out","w",stdout);
	double x,y,n;
	scanf("%lf%lf%lf",&x,&y,&n);
	printf("%.6lf",dfs(x,y,n));
	return 0;
}

其中\(dfs\)的三个参数分别为:当前的两条边、当前需要分的块数量。
你可能会问这样怎么保证最后的面积相等??我也有过这种问题,后来想明白了。
由于\(dfs\)的特性,在\(n/2==1\)的时候,当前这一层的\(dfs\)都会把最后剩下要分的部分分成相等的两块,总的来看,所有的\(dfs\)操作最后把整个蛋糕分成了相等的\(n\)块,也就是\(S=x*y/n\),那么我们理解了这一点之后按着题意来就行了

T3 最长距离 最气的题(不肯抄题解的倔强

当时以为正解是暴力枚举每个障碍物是否存在,再加一些小小的优化,没想到最短路,受教了,这道题也的的确确让我意识到最短路完全不用去解决纯的边权和最小问题,而是可以通过转化一些状态,再建立相应的边,通过最短路的算法来计算最小代价(言下之意就是抽象化了)

这道题最重要的地方就是!!:定义\(dis[i][j]\)为从当前点到\(i,j\)所需要\(\huge 移除的最少障碍量\)

这之后就是对于每一个图上的点跑一边\(spfa\),然后用一个\(record[i][j]\)数组记录当前状态到所有点的\(dis\)这里面有很多小细节,本人坑踩得足足的

\(\huge 警钟敲烂\),为了防止以后成傻逼,不惜时间成本一一列举犯傻的点

\(First\)

硬要用一种脑瘫\(hash\)方式来映射每一个点,没想到会很轻易地挂掉,因为在计算哈希的时候并不是双向的,用模运算的时候可能为\(0\),就直接\(g\)掉,以及一些边界情况都会出问题!!

点击查看代码
int calc(int x,int y){return m*(x-1)+y;}
void code(int &x,int &y,int t)
{
	x=t/m+1;
	y=x%m;
}

\(Second\)

就是喜欢在松弛操作里面边更新dis边更新record,成功的写错了下标

点击查看代码
	if(dis[c]>dis[calc(tmpx,tmpy)]+(mmap[x1][y1]=='1'?1:0))
			{
				rec[calc(tmpx,tmpy)][calc(i,j)]=dis[calc(i,j)];//这一行是错误的!!!
				dis[c]=dis[calc(tmpx,tmpy)]+(mmap[x1][y1]=='1'?1:0);
				if(!vis[calc(x1,y1)])qx.push(x1),qy.push(y1),vis[calc(x1,y1)]=1;
			}	

\(Third\)

就是刚刚那个地方把赋值写成了大于

点击查看代码
	if(dis[c]>dis[calc(tmpx,tmpy)]+(mmap[x1][y1]=='1'?1:0))
			{
				rec[calc(tmpx,tmpy)][calc(i,j)]=dis[calc(i,j)];//这一行是错误的!!!
				dis[c]>dis[calc(tmpx,tmpy)]+(mmap[x1][y1]=='1'?1:0);//喜欢复制粘贴?看看这行吧小子
				if(!vis[calc(x1,y1)])qx.push(x1),qy.push(y1),vis[calc(x1,y1)]=1;
			}	

最后含泪贴上ACimage

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,m,t;int rec[1000][1000];int dis[1000];bool vis[1000];
int calc(int x,int y){return m*(x-1)+y;}
bool valid(int x,int y){return 1<=x&&x<=n&&1<=y&&y<=m;}
double odis(int x,int y,int i,int j){return 1.0*(x-i)*(x-i)+1.0*(y-j)*(y-j);}
char mmap[35][35];
int c1[]={-1,0,1,0},c2[]={0,-1,0,1};
void spfa(int x,int y)
{
	queue<int>qx,qy;
	memset(dis,0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
	dis[calc(x,y)]=(mmap[x][y]=='1'?1:0);
	qx.push(x),qy.push(y);vis[calc(x,y)]=1;
	while(!qx.empty())
	{
		int tmpx=qx.front(),tmpy=qy.front();
		for(int i=0;i<=3;i++)
		{
			int x1=tmpx+c1[i],y1=tmpy+c2[i];
			if(!valid(x1,y1))continue;
			int c=calc(x1,y1);
			if(dis[c]>dis[calc(tmpx,tmpy)]+(mmap[x1][y1]=='1'?1:0))
			{
				dis[c]=dis[calc(tmpx,tmpy)]+(mmap[x1][y1]=='1'?1:0);
				if(!vis[calc(x1,y1)])qx.push(x1),qy.push(y1),vis[calc(x1,y1)]=1;
			}	
		}
		qx.pop(),qy.pop(),vis[calc(tmpx,tmpy)]=0;	
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			rec[calc(x,y)][calc(i,j)]=dis[calc(i,j)];
}
int main()
{
	scanf("%d%d%d",&n,&m,&t);
	char k=getchar();
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)mmap[i][j]=getchar();
		k=getchar();
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			spfa(i,j);
	
	double ans1=0;
	
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int x=1;x<=n;x++)
				for(int y=1;y<=m;y++)
					if(rec[calc(i,j)][calc(x,y)]<=t) ans1=max(ans1,odis(i,j,x,y));
	
//		for(int i=1;i<=n;i++)
//		for(int j=1;j<=m;j++)
//			for(int k=1;k<=n;k++)
//				for(int l=1;l<=m;l++)
//					printf("dis:%d %d--->%d %d==%d\n",i,j,k,l,rec[calc(i,j)][calc(k,l)]);
	printf("%.6lf",sqrt(ans1));
	return 0;
}

标签:27,int,x1,y1,include,2022.09,Test,calc,dis
From: https://www.cnblogs.com/Hanggoash/p/16736141.html

相关文章

  • 9.27
    T1生日快乐题目传送门虽然是水题,但很容易被误导成二分,没有证明的直觉不是直觉,但是题目没有卡这种错误的做法拿了\(70pts\),和二分相近,只不过每次将所有可能的情况都分出......
  • AtCoder Beginner Contest 266
    AtCoder五十连练第三练AtCoderBeginnerContest266D-SnukePanic(1D)高桥正试图抓住许多Snuke。有五个坑在坐标\(0,1,2,3,4\)号线,连接到Snuke的巢。现在,\(......
  • 20220927(平)
    20220927(平)t1[SCOI2009]生日快乐传送门思路​ 题目还是挺具有迷惑性的,至少我第一眼就以为是二分。然后就写了个二分,然而最后写出来是在二分里二分,又发现只有边长除......
  • 闲话 22.9.27
    闲话似乎没几个人把闲话设为显示但是我除了闲话没啥了所以不隐藏了而且主要的简介都在摘要里面了我等一等再去切risrqnis我还剩五个点和55pts(今天想到拉格朗日的......
  • LeetCode[279. 完全平方数]
    279.完全平方数本题我们可以把他理解成一个图论我们的每一个结点就是每一个数值加了平方项以后就从当前值转移到了另一个值BFS常见套路定义一个队列,队列中有元素就......
  • 9.27
    今日内容1.垃圾回收机制2.流程控制理论3.流程控制之分支结构4.流程控制之循环结构垃圾回收机制"""有一些语言内存空间的申请和释放都需要程序员自己写代码才可以完......
  • Cocos Creator用jtest单元测试攻略极速版
    主要参考了CocosCreator中单元测试入门,但是该文代码在我电脑上并没有正常执行,所以修正后写了本文。毕竟,一篇攻略,最基本的要求应该是,可以成功运作。想要了解到底是为什么......
  • 【闲话】2022.09.27闲话
    考试++今天大型机惨活动。明明只是去做了次核酸,怎么会变成这个样子呢?今天大型BA讨论活动L:泰国歌曲据说今晚\(\textrm{luogu}\)要修RMJ,希望明天会更好。......
  • 做题记录整理dp14 P5336 [THUSC2016]成绩单(2022/9/27)
    P5336[THUSC2016]成绩单这题难度标的虚高首先一眼区间dp,然后写出递推方程然后发现爆空间,再上离散化然后就没了。。。撑死也就是蓝题不过学到了一个离散化技巧#incl......
  • 2022-09-27 IOS 打包后图标背景变黑 Android 则正常
    前言:uniapp项目打包app,app的logo背景是透明的,打包后iso的图标背景是黑色,而Android则为透明,符合需求,至于ios为什么是黑色的,百度了一看有以下情况:图标的纤细信息里面的一个......