实验
修改了一点
等结果了
蓝桥杯
简单的练习题
Floyd
重点:
输入的时候也要小心重边
因为距离是《=10^9
所以d一定要用ll
const ll mod=0x3f3f3f3f3f3f3f3f;
scanf("%d%d%lld", &x, &y, &d);
dis[x][y] = min(dis[x][y],d);
dis[y][x] = min(dis[x][y],d);
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod=0x3f3f3f3f3f3f3f3f;
const int N = 105;
int n,m, q;
ll dis[402][402];
void floyd()
{
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
for (int k = 1; k <= n; k ++)
{
dis[j][k] = min(dis[j][i] + dis[i][k],dis[j][k]);
}
}
int main()
{
scanf("%d%d%d", &n, &m, &q);
memset(dis,mod, sizeof dis);
for (int i = 1; i <=n; i ++) dis[i][i] = 0;
for (int i = 1; i <= m ; i++)
{
int x, y;
ll d;
scanf("%d%d%lld", &x, &y, &d);
dis[x][y] = min(dis[x][y],d);
dis[y][x] = min(dis[x][y],d);
}
floyd();
for (int i = 1; i <= q; i ++)
{
int x, y;
scanf("%d%d", &x, &y);
if (dis[x][y] == mod)
printf("-1\n");
else
printf("%lld\n", dis[x][y]);
}
return 0;
}
完全背包
使用了一维数组
01背包dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]);
完全背包dp[i][j] = max(dp[i-1][j], dp[i][j-w[i]]+v[i]);
#include<iostream>
#include<cstdio>
using namespace std;
int n, V;
int f[1005];
int v[1005], w[1005];
int main()
{
scanf("%d%d", &n, &V);
for (int i = 1; i <= n; i ++)
scanf("%d%d", &w[i], &v[i]);
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= V; j ++)
{
if (j >= w[i])
f[j] = max(f[j], f[j-w[i]]+v[i]);
}
printf("%d", f[V]);
return 0;
}
美丽的区间
从一个数组中一个最短的连续区间的和>=V的区间长度
一开始想的前缀和,一直没想到如何用双指针,然后就两重循环了,那就O(N^2)了,超时
后来看了题解,才知道如何用双指针
#include<iostream>
#include<cstdio>
using namespace std;
int n, V;
int s[100010];
int main()
{
scanf("%d%d", &n, &V);
for (int i = 1; i <= n; i ++)
{
scanf("%d", &s[i]);
// s[i] += s[i-1];
}
int res = 100010;
int sum = 0;
for (int i = 1, j = 0; i <= n; i ++)
{
while (sum < V && j < n)
{
j ++;
sum += s[j];
// j ++;
}
if (sum >= V)
res = min(res, j - i + 1);
sum -= s[i];
}
if (res == 100010) printf("0\n");
else printf("%d\n", res);
return 0;
}
并查集
vue
响应式数据
基本类型的用 ref
对象的用 reactive