Test 2022.09.27

今天不知道是什么专场了,但是我知道的是我今天真的没有改完!!!!太气了,最短路的赋值号写成大于竟然不会报错,害得我改了半个下午一个晚上,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统计答案一直都是一个难点,注释都在代码里面了

点击查看代码

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=xy/n,那么我们理解了这一点之后按着题意来就行了

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

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

这道题最重要的地方就是!!:定义dis[i][j]为从当前点到i,j所需要

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

,为了防止以后成傻逼,不惜时间成本一一列举犯傻的点

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

点击查看代码
posted @   Hanggoash  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
动态线条
动态线条end
点击右上角即可分享
微信分享提示