标签:return 二十 int pos mid maxn Nothing include
题目:New Reform
题意:就是给你一个无向图,如果要把无向图改为有向图,怎么改使孤立节点最少,输出孤立节点的个数,孤立节点没有入度的点都是孤立节点。
思路:在一个联通块里面,如果不存在环的话,只有一个孤立的节点,如果存在环的话那么就没有孤立的节点,所以我们就用并查集去实现,是否存在环。如何判定呢,如果这两个点已经在一个联通块里面,那么这个联通块里面就存在环。
代码:
#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
const int N = 50010;
int fa[maxn];
bool vis[maxn];
int Find(int x)
{
if(x == fa[x])return x;
return fa[x]=Find(fa[x]);
}
int n, m, u, v;
int main(){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)fa[i] = i;
for(int i = 1; i <= m; i++){
scanf("%d %d", &u, &v);
int xx = Find(u);
int yy = Find(v);
if(xx == yy){//存在环
vis[xx] = 1;
}
else {
fa[yy] = xx;
if(vis[yy])vis[xx] = vis[yy];//如果yy中存在环,那么整个一定存在环
}
}
int cnt = 0;
for(int i = 1; i <= n; i++){//遍历一下
if(Find(i) == i && !vis[i])cnt++;
}
printf("%d\n", cnt);
return 0;
}
题目:Enduring Exodus
题意:给你一行0,1组成的字符串,1代表这个房间已经住满了,0代表这个房间还可以住人,一个人带着他的k头羊,怎么安排使羊距离这个人的距离最近,输出这个结果。
思路:这道题采用二分,二分去遍历距离,如果这个距离满足k+1空间那么这个距离就是OK的,找到最小的一个符合要求的。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int sum[maxn];
char a[maxn];
int n, m;
inline int check(int pos, int mid){
int l = max(1, pos-mid);
int r = min(n, pos+mid);
return (sum[r]-sum[l-1]-1) >= m;
}
inline int Bsearch(int pos, int l, int r){
while(l < r){
int mid = (l+r)>>1;
if(check(pos, mid))r = mid;
else l = mid+1;
}
return l;
}
int main(){
scanf("%d %d", &n, &m);
scanf("%s", a+1);
sum[0] = 0;
for(int i = 1; i <= n; i++){
sum[i] = sum[i-1] + (a[i] == '0');
}
int l = 1, r = n;
int ans = INT_MAX;
for(int i = 1; i <= n; i++){
l = 1, r = n;
if(a[i] == '0'){
ans = min(Bsearch(i, l, r), ans);
}
}
printf("%d\n", ans);
return 0;
}
题目:Xenia and Bit Operations
参考博客:CodeForces 339D Xenia and Bit Operations (线段树)
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int st[maxn<<2];
void pushup(int o, int ok){
if(ok) st[o] = st[o<<1|1]|st[o<<1];
else st[o] = st[o<<1|1]^st[o<<1];
}
void build(int o, int l, int r, int ok)
{
if(l == r)scanf("%d", &st[o]);
else
{
int m = l + ((r-l)>>1);
build(o<<1, l, m, !ok);
build(o<<1|1, m+1, r, !ok);
pushup(o, ok);
}
}
void update(int o, int l, int r, int ind, int ans, int ok)
{
if(l == r)
{
st[o] = ans;
return;
}
int m = l + ((r-l)>>1);
if(ind <= m)update(o<<1, l, m, ind, ans, !ok);
else update(o<<1|1, m+1, r, ind, ans, !ok);
pushup(o, ok);
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
int ok = (n&1);
n = (1<<n);
build(1,1,n, ok);
while(m--){
int p, b;
scanf("%d %d", &p, &b);
update(1, 1, n, p, b, ok);
printf("%d\n", st[1]);
}
}
题目:Report
题意:给你一个字符串,m个操作,ti,ri代表从1到ri进行从大道小的顺序或者从小到达的顺序,输出最后的顺序。
思路:暴力指定是行不通,所以只能找找规律换换思路,通过各种操作你会发现ri最大值之前的所有操作都是无效,所以我们的操作只在ri之后的有效,找到最大的ri之后你还想着暴力,那么一定会超时,所以只能再想办法优化了,看代码。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, m, t, x, y;
scanf("%d %d", &n, &m);
vector<int>a, op(n+2, 0), pos(n+2, 0);
for(int i = 1; i <= n; i++){
scanf("%d", &t);
a.push_back(t);
}
int maxx = 0;
vector<int> res = a, v = a;
for(int i = 1; i <= m; i++){
scanf("%d %d", &x, &y);
op[y-1] = x;
pos[y-1] = i;
maxx = max(maxx, y);
}
sort(v.begin(), v.begin()+maxx);
for(int i = maxx-1; i >= 0; i--){
if(pos[i] < pos[i+1]){
pos[i] = pos[i+1];
op[i] = op[i+1];
}
}
int l = 0, r = maxx-1;
for(int i = maxx-1; i >= 0; i--){
if(op[i] == 2)res[i] = v[l++];
else res[i] = v[r--];
}
for(int i = 0; i < res.size(); i++){
if(i != 0)printf(" ");
printf("%d", res[i]);
}
printf("\n");
return 0;
}
标签:return,二十,int,pos,mid,maxn,Nothing,include 来源: https://blog.csdn.net/REfusing/article/details/99676350
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。