Hello 2022(B,D)
B
这一个题我知道是找到一个或者是一个区间,他们的端点中一定存在最左端点和最右端点,每一个段都有一个价值,而选择一个段,就会获得该段的价值,求最小价值(我是这样的理解)
一开始我真的在纠结要在获得的新的一个端点和上一个边界一样要怎么更新(我想到了万一上一个的两端是聚集在一个区间的,而且比选这一个区间的价值要小,那么我可以选择不更新,万一下一个又和这一个在一起的价值更小,可是上一步我还没有更新,所以下一步就得不到最好的答案,想没有想清楚,真是烦)
然后我看了其他人的解法,比我的清楚不知道到哪里去了
这个解法的处理是我们有两个方案,一个是选择两个区间,一个是一个区间,只要有一个不满足条件就更新方案
只有当第二个方案的最左端点和最右端点和第一个方案时,那么就说明这一个方案是可以的,可以拿这一个方案和第一个方案选择最优解
详细见代码
#include <iostream>
#include <stdlib.h>
using namespace std;
const int maxn=1e5+10;
int t,n;
int l[maxn],r[maxn],c[maxn];
void solve()
{
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>l[i]>>r[i]>>c[i];
}
int id=1,idl=1,idr=1;
cout<<c[1]<<'\n';
int ans=0;
for (int i=2;i<=n;i++)
{
if (l[i]<l[idl])idl=i;
if (l[i]==l[idl]&&c[i]<c[idl])
{
idl=i;
}
if (r[i]>r[idr])idr=i;
if (r[i]==r[idr]&&c[i]<c[idr])
{
idr=i;
}
if (l[i]<l[id]||r[i]>r[id]||(l[i]==l[id]&&r[i]==r[id]&&c[i]<c[id]))
{
id=i;
}
if (idl==idr) ans=c[idl];
else ans=c[idl]+c[idr];
if (l[id]==l[idl]&&r[id]==r[idr])ans=min(ans,c[id]);
cout<<ans<<'\n';
}
return ;
}
int main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
C
交互题反正我是不会,也不想补(摆烂了)
D
这一个一开始我是不太明白的
看了题解才明白其中关键
题意是有2nX2n个网格
x表示行,y代表列
对于对于x行,那么对于这一行,每一个的列都减1,如(x,y)变成(x,y-1),但是注意(x,1)变成(x,2n)
对于对于y列,那么对于这一列,每一个的行都加1,如(x,y)变成(x+1,y),但是注意(2n,y)变成(1,y)
我们需要把在左上方(1,1到n,n块)的移动到右下块(n+1,n+1到n+n,n+n),清理到雪块的需要ci,j的费用,(ci,j=0时是没有雪块,只要有人会到达这个雪块,我们就要提前清理),问我们到达右下块最少需要的费用
进入右下块需要一个入口,我们有这么几个入口
(1,n+1)可以到达(n+n,n+1)
(1,n+n)可以到达(n+n,n+n)
(n,n+1)可以到达(n+1,n+1)
(n,n+n)可以到达(n+1,n+n)
(n+1,1)可以到达(n+1,n+n)
(n+1,n)可以到达(n+1,n+1)
(n+n,1)可以到达(n+n,n+n)
(n+n,n)可以到达(n+n,n+1)
然后每一个都需要从这一个入口来,其他的先进入的先占位置,然后在移动,这样一定会移动好的
在这一块的都会需要清除
#include <iostream>
#include <stdlib.h>
using namespace std;
#define int long long
const int maxn=500+10;
int c[maxn][maxn];
int n,t;
void solve()
{
cin>>n;
for (int i=1;i<=n*2;i++)
{
for (int j=1;j<=2*n;j++)
{
cin>>c[i][j];
}
}
int s=1e9;
s=min(s,min(c[1][n+1],c[1][n+n]));
s=min(s,min(c[n][n+1],c[n][n+n]));
s=min(s,min(c[n+1][1],c[n+1][n]));
s=min(s,min(c[n+n][1],c[n+n][n]));
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
s+=c[i+n][j+n];
}
}
cout<<s<<'\n';
return ;
}
signed main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
标签:端点,min,int,到达,一个,maxn,2022,Hello
From: https://www.cnblogs.com/righting/p/17018387.html