补坑,这套题太难了= =
t3看都不想看了果断弃疗,这套题思维难度直逼省选,第一题一看见最大的最小值就往二分答案上考虑,首先这道题给了一个矩形,二分答案之后就变成一个01矩阵,然后此题就变成了O(n*m*log(maxw[i])),百分之百的数据范围是10的10次方,除非数据故意卡你否则绝对能过(其实数据卡你也不一定会T)。
附上代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
long long int map[1010][1010],a[1010][1010],s[1010],n,m,tim,l,r;
int check(long long int x)
{
tim++;
for (int i=1;i<=n;i++)
{
int st=0;
for (int j=1;j<=m;j++)if (a[i][j]>=x)s[++st]=j;
for (int j=1;j<st;j++)
for (int k=j+1;k<=st;k++)//转换为01矩阵。
{
if (map[s[j]][s[k]]==tim)return 1;
map[s[j]][s[k]]=tim;
}
}
return 0;
}
int main()
{
freopen("build.in","r",stdin);
freopen("build.out","w",stdout);
cin>>n>>m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
scanf("%I64d",&a[i][j]);
if (r<a[i][j])r=a[i][j];
}
for ( long long int x;l<r;(check(x=l+r+1>>1))?l=x:r=x-1);//二分答案
printf("%I64d",l);
fclose(stdin);
fclose(stdout);
return 0;
}
第二题也是难啊,是洛谷的P1613跑路,看到2的k次方就应该想到倍增的QAQ,还是这类题目做少了,以后要注意读题= =,其实就是一个倍增问题,一开始先初始化使每两点的距离为INF(其实就是floyd的正常套路啦),然后枚举每个点判断两个点能否用1s到达,如果可以就将两点连上一条边,之后用floyd来处理一遍处理出来每两点之间的距离,从而得出第一个点与第n个点之间的距离,其实代码比较好写,但是思维难度略大。
附代码
#include<cstdio>
#include<iostream>
#define rep(i,x) for (register int i=1;i<=x;i++)
using namespace std;
int d[60][60],n,m,f[40][60][60],u,v;
int main()
{
freopen("run.in","r",stdin);
freopen("run.out","w",stdout);
cin>>n>>m;
rep(i,n)rep(j,n)d[i][j]=1<<28;//预处理
rep(i,m)
{
scanf("%d%d",&u,&v);
f[0][u][v]=d[u][v]=1;//读边,初始化距离为1的点
}
rep(k,31)rep(l,n)rep(i,n)rep(j,n)
{
if (f[k-1][l][j]+f[k-1][i][l]==2)f[k][i][j]=d[i][j]=1;//处理能够在1s之内到达点
}
rep(k,n)rep(i,n)rep(j,n)
if (d[i][k]+d[k][j]<d[i][j])
d[i][j]=d[i][k]+d[k][j];//floyd处理一遍
cout<<d[1][n];//输出答案
fclose(stdin);
fclose(stdout);
return 0;
}