目录
解析:
这是一道最短路问题,可以用迪杰斯特拉、bellford、floyd来做,不过由于这是一道填空题,没必要浪费太多时间,并且用肉眼看便能得出答案(6)。(以下代码非博主手写,都是从网上找回来的,便于读者学习最短路)
代码:
迪杰斯特拉
#include <iostream>
#include <cstring>
using namespace std;
const int N=200,n=19;
int dist[N];
int g[N][N];
void add(char x,char y,int c)
{
int a=x-'A'+1;
int b=y-'A'+1;
g[a][b]=g[b][a]=c;
}
bool vis[N];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&(t==-1||dist[j]<dist[t]))
t=j;
}
vis[t]=1;
for(int j=1;j<=n;j++)
{
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
return dist[n];
}
int main()
{
memset(g,0x3f,sizeof g);
add('A','B',2);
add('A','C',1);
add('A','D',1);
add('A','D',1);
add('B','J',2);
add('B','G',1);
add('C','D',3);
add('C','F',3);
add('C','G',3);
add('D','E',1);
add('D','G',2);
add('D','H',1);
add('D','I',2);
add('E','H',1);
add('E','I',3);
add('F','G',1);
add('F','J',1);
add('G','F',1);
add('G','I',3);
add('G','K',2);
add('H','I',1);
add('H','L',2);
add('I','M',3);
add('J','S',2);
add('K','N',1);
add('K','L',3);
add('K','P',2);
add('L','M',1);
add('L','R',1);
add('M','N',2);
add('M','Q',1);
add('M','S',1);
add('N','P',1);
add('O','P',1);
add('O','Q',1);
add('O','R',3);
add('R','S',1);
cout<<dijkstra();
return 0;
}
floyd
#include <iostream>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
const int n = 20;
int g[n][n];
int main()
{
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
if (i == j) g[i][j] = 0;
else g[i][j] = INF;
g[1][3] = 1;
g[3][1] = 1;
g[1][2] = 2;
g[2][1] = 2;
g[1][4] = 1;
g[4][1] = 1;
g[1][5] = 1;
g[5][1] = 1;
g[2][7] = 1;
g[7][2] = 1;
g[2][10] = 2;
g[10][2] = 2;
g[3][4] = 3;
g[4][3] = 3;
g[3][7] = 3;
g[7][3] = 3;
g[3][6] = 3;
g[6][3] = 3;
g[4][7] = 2;
g[7][4] = 2;
g[4][5] = 1;
g[5][4] = 1;
g[4][8] = 1;
g[8][4] = 1;
g[4][9] = 2;
g[9][4] = 2;
g[5][8] = 1;
g[8][5] = 1;
g[5][9] = 3;
g[9][5] = 3;
g[6][7] = 1;
g[7][6] = 1;
g[6][10] = 1;
g[10][6] = 1;
g[7][9] = 3;
g[9][7] = 3;
g[7][11] = 2;
g[11][7] = 2;
g[8][9] = 1;
g[9][8] = 1;
g[8][12] = 2;
g[12][8] = 2;
g[9][13] = 3;
g[13][9] = 3;
g[10][19] = 2;
g[19][10] = 2;
g[11][17] = 2;
g[17][11] = 2;
g[11][12] = 3;
g[12][11] = 3;
g[11][14] = 1;
g[14][11] = 1;
g[12][18] = 1;
g[18][12] = 1;
g[12][13] = 1;
g[13][12] = 1;
g[13][14] = 2;
g[14][13] = 2;
g[13][16] = 1;
g[16][13] = 1;
g[13][19] = 1;
g[19][13] = 1;
g[14][17] = 1;
g[17][14] = 1;
g[15][16] = 1;
g[16][15] = 1;
g[15][17] = 1;
g[17][15] = 1;
g[15][18] = 3;
g[18][15] = 3;
g[18][19] = 1;
g[19][18] = 1;
// C++ Version
//floyd板子
for (int k = 1; k <= n; k++) {
for (int x = 1; x <= n; x++) {
for (int y = 1; y <= n; y++) {
g[x][y] = min(g[x][y], g[x][k] + g[k][y]);
}
}
}
cout << g[1][19] << "\n";
return 0;
}
B 修改数组
前情:
这道题博主试了一下暴力,结果有80分和90分,那么它们的区别在哪呢?
上面的代码80分,下面的90分。为什么呢?我们可以看到上面的是用cin输入以及用bool来标记,而下面是用scanf和int来判定。众所周知,cin读取的速度是比scanf慢的,至于慢多少我也不知道,不过我想告诉大家的是:这道题必须得用scanf和int声明的数组才可以得90分。我试过单用scanf一样是80分,单用int声明的数组也是80分,用cin或bool数组依旧是80分,只有用int声明的数组+scanf才是90分,这说明什么?告诫我们没事多用scanf和int声明的数组,少用cin和bool。
#include <bits/stdc++.h>//80
using namespace std;
const int maxn=1e6+10;
bool vis[maxn];
int main() {
int n,a;
cin>>n;
for(int i=0; i<n; i++) {
cin>>a;
while(vis[a]) a++;
cout<<a<<' ';
vis[a]=true;
}
return 0;
}
#include <bits/stdc++.h>//90
using namespace std;
int vis[1000005];
int main() {
int n,a;
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%d",&a);
while(vis[a]) a++;
cout<<a<<' ';
vis[a]=1;
}
return 0;
}
解析:
这是一道并查集的题目。怎么想到是并查集的呢?我们由暴力可以得出,只要该数用过就标记,然后往后继续遍历查找未用过的数,这样做的话复杂度平均是O(n^2),最坏高达O(n^2logn),无疑必爆,可是蓝桥官网居然有90分(不能理解,不过这告诉我们这还是个暴力杯)。由于这道题可以看作若干个集合,大家都知道集合是互异性,所以如果重复出现的需要一直+1,直到未曾用过。又因为并查集是将每个数组初始化为i,然后find是找根节点,这样我们可以将已经用过的点压到子节点里,更新根节点,所以只要对已用的集合+1并压入子节点就行了。
这一种并查集是没有初始化的,下面那种并查集是初始化的了(!!!注意注意:下面初始化并查集时,不要只初始到n,不见得题目给出的数值就一定是n以内,博主就是卡死在了n这里)
代码:
#include <bits/stdc++.h>
using namespace std;
int p[100005],n;
int find(int x) {
return p[x]==0 ? x : p[x]=find(p[x]);
}
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
int a;
cin>>a;
int x=find(a);
p[x]=x+1;
cout<<x<<" ";
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int p[1000010],n;
void init() {
for(int i=1; i<=1000005; i++)
p[i]=i;
}
int find(int x) {
return p[x]==x ? x : p[x]=find(p[x]);
}
int main() {
cin>>n;
init();
for(int i=1; i<=n; i++) {
int a;
cin>>a;
int x=find(a);
p[x]=x+1;
cout<<x<<" ";
}
return 0;
}