A - Minimum’s Revenge_规律

题意:

给你n个点,每个点编号从1-n,任意两个点之间连线的权值为这两个点编号的最小公倍数,问这n个点的最小生成树的权值和。

题解:

设任意两个点编号的最小公倍数肯定大于等于最大的编号,编号1与其他编号的最小公倍数等于其他编号,所以直接把其他编号的点与编号为1的点相连就是最小生成树了,权值和为 2 + 3 + ······ + n,所以公式: 

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)1e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int main()
{int T; scanf("%d", &T);int len = 0;while(T--){ll n; cin>>n;printf("Case #%d: %lld\n", ++len, (2 + n) * (n - 1) / 2);}
}

B - Prediction_并查集+思维+dfs

题意:

给你一个一棵有n个点m条边的图,再给你一个与这个图对应的m个节点的树,树上的每个节点对应图中的一条边。
然后进行q次查询,每次查询给你一个树中点的集合,对于每次查询应计算:这个集合中的所有点 and  集合中点的所有祖先节点所代表的边,把这些边连起来所构成的联通块的个数。

题解:

首先合并问题考虑到并查集,然后由于查询的时候每个点以及这个点对应其所有祖先节点所代表的边都要连起来,那么如果每次都遍历集合中的点以及其所有祖先节点显然不合理,很可能超时。  所以可以让每一个节点都维护一个并查集(该节点的边以及其所有祖先节点对应的边都并在该节点维护的并查集中了)。

由于题目的特殊性,查询时给你的集合中的点,其父亲节点也算,所以可以从父亲节点往下推。根据这个特点,建立每个点所维护的并查集时,不应该每次从头遍历,太费时间了,可以继承其父亲的并查集然后再加并上自身的边。这样一来dfs一次就把所有节点的对应的并查集都初始化好了。

以后查询的时候只需要把对应集合中的每个点维护的并查集都再并一下,记录合并的边数,最后用总边数减去其就是答案了。

如果不明白可以直接看明白题目后看代码,有详细注释。

代码:

#include<iostream>
#include<cstdio>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define up(i, x, y) for(int i = x; i <= y; i++)
#include<cmath>
#define MAXN ((int)1e4 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
// 说明:树上的点k作为注释里面所说的维护的k号并查集,也就是树上节点是多少维护的并查集就是几号
int n, m;
vector<int> G[MAXN];  //存树
pair<int,int> e[MAXN]; //存图的边
int pre[MAXN][500 + 10]; //每个顶点维护一个并查集
int d[500 + 10];inline int find_(int x, int t) // 查询t点维护的t号并查集
{return x == pre[t][x] ? x : pre[t][x] = find_(pre[t][x],t);
}
//加上inline快了将近600ms,所以向这种常用的,且简短递归程度不高的语句最好写成内联函数
//定义为内联函数,再编译的过程中就会把这个函数放到需要它的地方,不用调用了,但是会增加内存大小void dfs(int u, int fa)
{up(i, 1, n) pre[u][i] = pre[fa][i]; // 接用父亲节点已经处理好的并查集int fx = find_(e[u].first, u);int fy = find_(e[u].second, u);if(fx != fy) pre[u][fx] = fy;//合并边,树上的u这个点对应着的边是从点e[u].first到e[u].second//所以不仅要继承父亲并查集的内容,还要顾到自己的边for(int i = 0; i < G[u].size(); i++){int v = G[u][i];dfs(v, u); //往下”继承“,也就是接着维护u子节点对应的并查集。}
}int main()
{int T; scanf("%d", &T);up(cas, 1, T){scanf("%d %d", &n, &m);up(i, 1, m) G[i].clear(); //初始化up(i, 2, m){int t; scanf("%d", &t);G[t].push_back(i); // t 连向 i , 父节点指向子节点,建树}up(i, 1, n) pre[1][i] = i;//对1号并查集进行初始化,也就是父节点对应的并查集up(i, 1, m) scanf("%d %d", &e[i].first, &e[i].second);//树上每个顶点对应着的边dfs(1, 1);int q; scanf("%d", &q);printf("Case #%d:\n", cas);while(q--) //每一个查询,用0号并查集把他们并起来{int t; scanf("%d", &t);up(i, 1, n){pre[0][i] = i; // 0号并查集初始化}int ans = n; //初始有n块联通up(i, 1, t){int a; scanf("%d", &a);up(j, 1, n)  //合并a号并查集{int fy = find_(j, a);//查询a号并查集if(fy != j) // 不等于j说明j这个点不是孤立的,而是a号并查集所并起来的点,所以要把这个点用0号并查集合并起来。{int x = find_(fy, 0); //在0号并查集中查询int y = find_(j, 0);if(x != y){ans--; //合并了,所以少一个联通pre[0][x] = y; //更新0号并查集}}}}printf("%d\n", ans);}}return 0;
}

是否用内联函数的效果对比:

使用内联函数    :时间:1014 ms  内存:23.6 MB
未使用内联函数:时间:1606 ms  内存:22.8 MB

C - Mr. Frog’s Problem_数学

题意:

题解:

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)1e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int main()
{int T; cin>>T;int len = 0;while(T--){ll a, b; cin>>a>>b;if(a == b){printf("Case #%d:\n1\n%lld %lld\n", ++len, a, b);}else{printf("Case #%d:\n2\n%lld %lld\n%lld %lld\n", ++len, a, b, b, a);}}
}

D - Coconuts_坐标离散化技巧

题意:

给你一个R * C的矩阵,然后给你n个点,问你由这n个点把这个矩阵分成了几大块,从小到大的顺序输出每一大块里1*1的小块的数目。0<R,C≤10^9   0≤n≤200

题解:

首先观察数据范围,这个矩阵最大为 10^9 * 10^9 的一个矩阵,太大了,bfs直接搜根本不可行,再来观察n,它最大才200,所以可以把这个矩阵离散化(乘坐标离散化,具体算法举例可参照小白皮(挑战程序设计竞赛) P164)

利用坐标离散化把矩阵主要特征(这n个点的整体相对位置)保留,还有一个麻烦的地方就是让求每大块内的个数,如果离散化后个数的特征就会消失。所以可以设一个数组P,来保存这个特征,也就是在压缩矩阵的过程中计算压缩后的一小块是由之前的多少块压缩过来的。

代码会有详细注释,还有不明白的可参照代码注释。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)1e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int T, n, m, sum, len, e;
int nxt[4][2] = {0, -1, -1, 0, 0, 1, 1, 0}; // bfs遍历用的
ll P[1000][1000];  //保留每一小块是由几个小块压缩过来的
int x1[1000], y1[1000];  //保留那n个点
bool path[1000][1000];  //记录离散化之后的矩阵
ll ans[1000];           //保留结果,最后升序输出
int tt[2];              //离散化之后返回压缩后的矩阵的高和宽
bool vis[1000][1000];   //bfs标记用
int loc;
void compress(int *x1, int *x2, int n, int m)
{int tmp[2];vector<int> xs, ys;xs.push_back(0); xs.push_back(n);//为了计算每一小块是由多少块压缩过来的,需要把端点加入进去,保留足够特征ys.push_back(0); ys.push_back(m);//比如(0, 0)点之后的点想计算压缩之前的块数,需要往前减和往上,可以把增//加的两端的点理解为两边放了两堵墙,卡住,为了可以计算压缩后每个点代表的实际块数for(int i = 1; i <= len; i++){for(int d = -1; d <= 1; d++){ //每一关键点的相邻的地方保留相关信息int dx = x1[i] + d, dy = y1[i] + d;if(dx >= 1 && dx <= n) xs.push_back(dx);// 关键信息点,为离散化做准备if(dy >= 1 && dy <= m) ys.push_back(dy);}}sort(xs.begin(), xs.end()); //把关键信息排序sort(ys.begin(), ys.end());xs.erase(unique(xs.begin(), xs.end()), xs.end());  //删除重复的关键信息ys.erase(unique(ys.begin(), ys.end()), ys.end());for(int i = 1; i < xs.size(); i++){for(int j = 1; j < ys.size(); j++){P[i][j] = ll(xs[i] - xs[i - 1]) * ll(ys[j] - ys[j - 1]);  //保留每一个点是由多少个点压缩过来的特征}}for(int i = 1; i <= len; i++){x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin(); // 求离散化之后那n个点的位置y1[i] = find(ys.begin(), ys.end(), y1[i]) - ys.begin();path[ x1[i] ][ y1[i] ] = 1; //保留那n个点的位置}tt[0] = xs.size() - 1;  // 减去多加的 0这个点,当初加0也是为了计算每一个点是由多少个点压缩过来的特征,0不在矩阵内tt[1] = ys.size() - 1;}
void dfs(int x, int y)
{path[x][y] = 1; //当vis用了,这样就少开一个vis数组ans[loc] += P[x][y];//计算块数for(int i = 0;i < 4; i++){int dx = x + nxt[i][0], dy = y + nxt[i][1];if(dx >= 1 && dx <= tt[0] && dy >= 1 && dy <= tt[1] && !path[dx][dy])dfs(dx, dy);}
}int main()
{scanf("%d", &T);while(T--){loc = 0;memset(path, 0, sizeof(path));memset(ans, 0, sizeof(ans));scanf("%d %d", &n, &m);scanf("%d", &len);for(int i = 1; i <= len; i++){scanf("%d %d", &x1[i], &y1[i]);}compress(x1, y1, n, m); //坐标离散化for(int i = 1; i <= tt[0]; i++){  //bfs离散化之后的图,并记录答案ans[]for(int j = 1; j <= tt[1]; j++){if(!path[i][j]){loc++;dfs(i, j);}}}sort(ans + 1, ans + 1 + loc); //升序printf("Case #%d:\n%d\n", ++e, loc);up(i, 1, loc) printf("%lld%c", ans[i], i == loc ?  '\n' : ' ');}
}

E - Mr. Frog’s Game_暴力

题意:

给你一个连连看的图,每一种数字代表一种图标,问你是否可以消去一对,是输出Yes 反之

题解:

遍历第一行最后一行,第一列最后一列,如果有相同的那么可以连
遍历每一行每一列,看看是都有相邻的,如果有相邻的也可以连
否则不可以连,因为最初的图是满的那么连相邻的,要么连最外围的。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)1e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int G[50][50];
int main()
{int T; scanf("%d", &T);int len = 0;while(T--){int n, m ; scanf("%d %d", &n, &m);up(i, 1, n) up(j, 1 ,m) scanf("%d", &G[i][j]);map<int, int> mp;mp.clear();up(i, 1, m) // 第一行{mp[G[1][i]]++;if(mp[G[1][i]] > 1){goto stop;}}mp.clear();up(i, 1, m) //最后一行{mp[G[n][i]]++;if(mp[G[n][i]] > 1){goto stop;}}mp.clear();up(i, 1, n) //第一列{mp[G[i][1]]++;if(mp[G[i][1]] > 1){goto stop;}}mp.clear();up(i, 1, n) //最后一列{mp[G[i][m]]++;if(mp[G[i][m]] > 1){goto stop;}}up(i, 1, n)  //每一行{up(j, 2, m){if(G[i][j] == G[i][j - 1]) goto stop;}}up(i, 1, m) //每一列{up(j, 2, n){if(G[j][i] == G[j - 1][i]) goto stop;}}printf("Case #%d: No\n", ++len);continue;stop : {}printf("Case #%d: Yes\n", ++len);}
}

F - Auxiliary Set_思维+dfs

题意:

给你一棵树,然后又q次询问,每次询问会给你m个不重要的点,且规定两个重要的点的最小公共祖先也是重要的点,即使它在给定的不重要的点中。每次查询输出重要点的数目 = 开始给的重要的点的数目 + m个不重要的点中重要的点(这个重要的点就是两个重要点的最小公共祖先)。

题解:

这里不用tarjan算法去做,而把这个题作为一个思维+dfs的题目来看。(LCA 最近公共祖先,Tarjan(离线)算法感兴趣的推荐看这个博客:https://www.cnblogs.com/JVxie/p/4854719.html

假设一个不重要的点如果他有至少两个子树,并且至少两棵子树中每棵子树如果有重要的点,那么这个节点也就是重要的点。所以只需要用dfs遍历下求一下每个节点的直系儿子节点,也就是有几棵子树,然后记录下来。最后根据题目提供的不重要的点,先把这些不重要的点按照深度排序,然后就可以保证从树底部往树根推,如果一个点不是重要节点那么就删除,因为不是重要节点没什么用,只有从树底往上推才可以保证如果一个节点有两个以上的子树,那么该节点就是重要节点。

具体可以看代码,注释很详细。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)1e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n, q;
vector<int> vec[MAXN];
int root = 1;
void init() {for(int i = 0; i <= n; i++) vec[i].clear(); }
int fa[MAXN], dep[MAXN], son[MAXN];
int tmp[MAXN], imp[MAXN];
void dfs(int now, int pre, int d) //pre是now的父节点
//now为当前节点   pre是当前节点的父节点  d是当前树的深度
{fa[now] = pre; dep[now] = d; son[now] = 0;for(int i = 0; i < vec[now].size(); i++) //找当前节点的子节点{int v = vec[now][i];if(v == pre) continue;// 如果当前节点的儿子等于当前节点的父亲,瞎扯,肯定不行,返回,这是由于存的双向边导致的这种情况发生dfs(v, now, d + 1);//往下递归找下去son[now]++;//递归回来的时候记录直系子节点的数目}
}bool cmp(int a, int b)
{return dep[a] > dep[b]; //深度降序排序
}int main()
{int T; scanf("%d", &T);for(int case_ = 1; case_ <= T; case_++){printf("Case #%d:\n", case_);init(); //初始化vector;scanf("%d %d", &n, &q); // 树上n个点,q次询问for(int i = 1; i < n; i++){int a, b; scanf("%d %d", &a, &b);vec[a].push_back(b);vec[b].push_back(a);//建立双向边}dfs(1, 0, 0);//树根为 1while(q--){int x; scanf("%d", &x);//x是不重要节点的数目for(int i = 1; i <= x; i++){scanf("%d", &imp[i]); //不重要的点tmp[ imp[i] ] = son[ imp[i] ];//得到这个不重要的点有几个直系节点,也就是有几棵子树//用tmp保留一下,防止后面删除操作时破坏了原来的son数组}sort(imp + 1, imp + 1 + x, cmp);//把这些不重要的点按深度,从大到小排,也就是离根节点远的不重要的点在前面//这是为了一会查询子树的时候,保证每个子树都可以提供一个有用的点//因为是从树底部往上找的,如果一个节点是不重要的,那么就要把这个//不重要的节点的父节点的子树减去1,这样一来从下往上走一遍就好了int ans = 0;for(int i = 1; i <= x; i++){if(tmp[ imp[i] ] >= 2) ans++;//如果子树大于等于两个,又由于从下至上找的,可以保证每个子树都有一个重要节点//所以答案++else if(tmp[ imp[i] ] == 0) tmp[ fa[ imp[ i ]]]--;//如果为0的话,说明其父节点的该子树的无法提供重要节点,那么需要删去}printf("%d\n", ans + (n - x) ); // 新增的重要节点 + 原来题目提供的重要节点数目}}
}

H - Basic Data Structure_模拟+规律+双端队列

题意:

让你模拟实现一个新的类似于栈的数据结构,该数据结构可以具有以下操作:

1、插入到栈顶
2、从栈顶弹出
3、栈反转,栈头变栈底,栈底变栈头
4、查询,查询时从栈顶元素一直进行nand运算直到栈底,最后输出结果
  0 nand 1 == 1 nand 0 == 0 nand 0 == 1           1 nand 1 == 0

题解:

对于栈可以用数组实现,最初位置在中间,规定一个方向dir,dir为正时就右边就是栈顶,反之左边是栈顶,这样就可以很容易实现反转还有插入删除操作。

对于查询操作,如果遍历一遍的话会超时,所以观察 nand 运算的特点,假设从右向左进行nand运算,那么当运算到最左边的0的时候一定是1,如果最左边的0右边还有其他元素。所以可以分四种情况讨论。
1、当没有元素的时候直接输出 Valid.
2、当栈中全部是1的时候,直接看1个数的奇偶性,如果是奇数最后是1,反之是0
3、设栈里有a个元素,拿当最右边是栈顶时举例子,这时候,如果最左边的0恰好是栈顶元素,说明这个栈中只有最右边的元素是0,这时候就可以看作有 a - 1 个1,然后根据1的个数的奇偶性就好了。
4、除了以上特殊的情况外,还是拿最右边是栈顶时举例子,这时候进行查询时,只需要关注最左边的0的位置就好,因为从右往左计算到最后一个0时,这时候一定是1,最后结果是多少就要看1的个数的奇偶性了。

为什么会有3、4这俩分开呢,举个例子:(设右边是栈顶)
① 如:1 1 0   最后计算到最左边的0,剩的1的位置应该是: 1 1 
② 如:1 0 1   最后计算到最左边的0,剩的1的位置应该是: 1 1 
虽然最后结果1的位置一样 ,但是你会发现,①中的运算到最左边的0的位置是0, 而②中的运算到最左边的0的位置是1,这会导致最后0的位置与最终1的个数有个1的差别,这里没明白没关系,看下代码就懂了,有详细注释。

可以用双端队列保存0的位置。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)2e5 + 10)
#define INF 0x3f3f3f3f
using namespace std;
int st[MAXN * 2 ]; //开两倍的数组,因为会有反转操作,所以栈底为数组的中间位置
int l, r; //记录栈的两端位置
int dir; //记录是否反转,dir > 0, l是栈底,反之。
deque<int> que; // 双端队列,保存0的位置
typedef long long ll;
int main()
{int T, pp = 0; scanf("%d", &T);while(T--){printf("Case #%d:\n", ++pp);que.clear(); // 清零l = MAXN, r = MAXN - 1; //栈初始化,当l > r栈为空dir = 1; //栈初始化int n; scanf("%d", &n);while(n--){char str[10]; scanf("%s", str);if(str[2] == 'S'){ // 当PUSH操作时int t; scanf("%d", &t);if(dir) st[++r] = t; // 右边是栈顶,所以++relse st[--l] = t;     //反之if(t == 0){  //用队列记录0所处位置if(dir) que.push_back(r);else que.push_front(l);}}else if(str[2] == 'P'){if(dir){if(st[r] == 0) que.pop_back();//如果删除的是0,那么队列里对应的0的位置也需要删除r--;}else{if(st[l] == 0) que.pop_front();//同上l++;}}else if(str[2] == 'E'){if(r < l){puts("Invalid."); continue;}  //栈空if(que.empty()) {printf("%d\n", (r - l + 1) & 1); continue;}//没有0,全是1,所以直接看1的个数是奇数还是偶数// n是偶数 :n & 1 == 0; n是奇数: n & 1 == 1if(dir){if(que.front() == r) printf("%d\n", (r - l) & 1);//如果右边是栈顶,那么看最左边0的位置,如果最左边的0在栈顶,那么就是有(r - l)个1else printf("%d\n", (que.front() - l + 1) & 1);//如果不是上面这种特殊情况,那么直接算最左边有几个相连的1就好,最左边的0也是1,//因为最左边的0的右边还有数,只要有数,那么从栈顶到栈底的时候就会在这个0处产生1}else{if(que.back() == l) printf("%d\n", (r - l) & 1);//同上else printf("%d\n", ( r - que.back() + 1) & 1);}}else{dir = 1 - dir; // 1 - 0 == 1 ; 1 - 1 == 0; 反转 也可以 dir ^= 1}}}
}

J - Mission Possible_线性规划

题意:

一个人从起点出发要走过距离D,每秒他会收到A点伤害(持续受到),他的初试血量为H=0,速度为V=0,生命恢复为R=0(每秒末回复R点生命值,不是持续的),最初购买一点血量、速度、生命回复的花费分别为GH、GV、GR。要求走到终点的过程中生命值大于等于0,问最小花费是多少?

题解:

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define MAXN ((int)1e5 + 10)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
ll D, A, G1, G2, G3;
int main()
{int T; scanf("%d", &T);up(case_, 1, T){scanf("%lld %lld %lld %lld %lld", &D, &A, &G1, &G2, &G3);printf("Case #%d: ", case_);ll ans = INF;up(V, 1, D) ans = min(ans, G2 * V +  min( (ll)ceil( A * 1.0 * D / V ) * G1, A *  (G1 + G3)) );cout<<ans<<endl;}
}

SDNU_ACM_ICPC_2019_Winter_Practice_9th题解相关推荐

  1. [JS][dfs]题解 | #迷宫问题#

    题解 | #迷宫问题# 题目链接 迷宫问题 题目描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 1, 1 ...

  2. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  3. [JS]题解 | #魔法数字#

    题解 | #魔法数字# 题目链接 魔法数字 题目描述 牛妹给牛牛写了一个数字n,然后又给自己写了一个数字m,她希望牛牛能执行最少的操作将他的数字转化成自己的. 操作共有三种,如下: 在当前数字的基础上 ...

  4. [JS]题解 | #岛屿数量#

    题解 | #岛屿数量# 题目链接 岛屿数量 题目描述 时间限制:1秒 空间限制:256M 描述 给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右 ...

  5. [JS] 题解:提取不重复的整数

    题解:提取不重复的整数 https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1 时间限制:1秒 空间限制:32M 描述 输 ...

  6. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  7. [洛谷1383]高级打字机 题解

    题解 这道题一看就珂以用主席树啊 这是一道神奇的题目,那么我们先敲一个主席树,然后维护一个数组len,表示下一次应该在len + 1插入, 之后对于T操作,在上一个版本的len + 1上直接执行插入 ...

  8. luogu P1549 棋盘问题(2) 题解

    luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...

  9. 【题解搬运】PAT_L1-009 N个数求和

    从我原来的博客上搬运.原先blog作废. (伪)水题+1,旨在继续摸清这个blog(囧 题目 就是求N个数字的和.麻烦的是,这些数字是以有理数"分子/分母"的形式给出的,你输出的和 ...

最新文章

  1. SIPp工具Linux下安装
  2. Windows 如何在cmd命令行中查看、修改、删除与添加环境变量
  3. springboot 打卡功能_实战:如果让你用SpringBoot实现签到奖励的功能,你会怎么做?...
  4. 求1/2+1/4+...+1/n
  5. kafka生产者、消费者消息操作命令
  6. Python的3种字符串格式化,做个超全对比!
  7. python序列元素的编号称为_Python序列
  8. 【渝粤教育】电大中专混凝土结构作业 题库
  9. 关于“数据中心”的最强入门科普
  10. Linux Shell笔记2 函数
  11. 【中国传媒大学】史上最全的《电视原理》笔记
  12. 很有意思的HDB3编解码--C++实现
  13. roc曲线spss怎么做_如何用SPSS做ROC曲线分析
  14. Linux下使用FastDFS
  15. ubuntu的初始密码
  16. erb自动生成html页面一例
  17. IDA Pro与x64dbg联动调试记录
  18. 2022年四川二级建造师建设工程法规及相关知识《解决建设工程纠纷法律制度》练习及答案
  19. Python_首字母大写
  20. 卸下浮躁 回归本心 回归技术

热门文章

  1. 全网详解如何设计数据库的ER图,即实体关系图
  2. iOS-检查版本更新
  3. Router中如何设置光标以全屏十字架显示
  4. Java后端开发工程师
  5. CPU之外,国产芯片再突破,再也不用看AMD和NVIDIA的脸色了
  6. Shell-基础部分
  7. 用脚本组装xgen 后期文件,缓存正确,毛发飞的可能分析
  8. tensorflow2计算flops
  9. 全球围剿下,苹果还能挺多久?
  10. Fortran编程(VScode配置)——笔记2