首先我是暴力做的,我把每一个’#‘的
x
,
y
x,y
x,y记录下来,然后把每次顺时针旋转90的位置也记录下来,最后只要有一种旋转后的结果中’#'的相对
x
,
y
x,y
x,y之差相同即输出Yes,否则输出No。代码写的有点乱(因为这题卡了好久所以有点裂),其实很好实现的,也算个水题吧,但是他这个题目意思真的阴间
题目的意思就是问能找到多少对点(四个点)能组成长方形,当时想着就是暴力能不能过,结果还是tle了,看了下题解,原来对于vector可以直接二分(二分返回值是bool型),所以我们就直接先sort一下我们储存的坐标,然后
O
(
n
2
)
O(n^2)
O(n2)找一个左下角的点和右上角的点,然后用二分查找一下是否有左上角和右下角的点即可。
代码如下:
#include<bits/stdc++.h>usingnamespace std;intmain(){int n;
cin >> n;
vector<pair<int,int>>v(n);for(int i =0; i < n; i++)
cin >> v[i].first >> v[i].second;sort(v.begin(), v.end());int ans =0;for(int i =0; i < n; i++)for(int j =0; j < n; j++)if(v[i].first < v[j].first && v[i].second < v[j].second){if(binary_search(v.begin(), v.end(),make_pair(v[i].first, v[j].second))&&binary_search(v.begin(), v.end(),make_pair(v[j].first, v[i].second)))
ans++;}
cout << ans << endl;}
E - Destruction
思路分析
题目先给我们一个图,然后要我们去删边,使得他最后依然连通。结果要求删的边的边权加起来最大,相信很多人看到这个题目就知道是一个最小生成树的题吧,但是这题有坑,就是我们用
K
r
u
s
k
a
l
Kruskal
Kruskal做的话,如果我们把最小生成树构造出来了,但是还有负边权的边。因为如果我们选择删除这些负边权的边的话,我们就得不到最大值,所以那些负边无需拿出来
那么我的实现方法还是很笨的,就是我在读入的时候就把边标记为
0
0
0,表示没有用到(指构造最小生成树的时候),那么在用
K
r
u
s
k
a
l
Kruskal
Kruskal后再循环一下所有边,如果那条边没有被用来构造并且他的边权是正数,我们就
a
n
s
+
边
权
ans+边权
ans+边权。
#include<bits/stdc++.h>#definelllonglongusingnamespace std;constint maxn =1e6+10;structedge{int u, v;bool vis;
ll w;} edges[maxn];int fa[maxn];int n, m;voidinit(){for(int i =1; i <= n; i++){
fa[i]= i;}}intfind(int x){return fa[x]== x ? x : fa[x]=find(fa[x]);}boolcmp(edge a, edge b){return a.w < b.w;}voidkruscal(){for(int i =1; i <= m; i++){int fu =find(edges[i].u), fv =find(edges[i].v);if(fu != fv){if(fu > fv)swap(fu, fv);
fa[fv]= fu;
edges[i].vis =1;}elsecontinue;}}intmain(){scanf("%d %d",&n,&m);init();for(int i =1; i <= m; i++){scanf("%d %d %lld",&edges[i].u,&edges[i].v,&edges[i].w);}sort(edges +1, edges +1+ m, cmp);kruscal();
ll ans =0;for(int i =1; i <= m; i++){if(edges[i].vis ==0&& edges[i].w >=0){
ans += edges[i].w;}}printf("%lld", ans);return0;}