比赛连接:Dashboard - CodeTON Round 4 (Div. 1 + Div. 2, Rated, Prizes!) - Codeforces

A. Beautiful Sequence

题意:

t(1≤t≤500)组测试每组给定大小为n(1≤n≤100) 的序列,判断它是否存在一个子序列是好序列。一个序列是好序列当且仅当至少存在一个ai=i。

思路:

考虑到从原序列抽取一些数形成的子序列下标i只可能比原来小,如果原来存在一个i>=a[i],存在一种选择方法使得子序列下标i减小到a[i],否则不可能构造出来。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<iomanip>
#include<list>
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(),(x).end()
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const db pi=acos(-1.0);
const int N=110,M=2*N;
int a[N];
inline void solve()
{int n;cin>>n;rep(i,1,n+1) cin>>a[i];rep(i,1,n+1){if(i>=a[i]){cout<<"YES"<<endl;return;}}cout<<"NO"<<endl;
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int _=1;cin>>_;while(_--){solve();}return 0;
}

B. Candies

题意:

t(1≤t≤1e4)组测试每组给定n(2≤n≤1e9) ,有两种操作,第一种是将x变为2*x-1,第二种是将x变为2*x+1,输出将1变为n的操作序列,最多不超过40次。

思路:

操作后的数只能变为奇数,故n为偶数时一定不能构造。n为奇数,考虑如何使n变为1,如果把n写为二进制形式,第一种逆操作相当于将n加一再右移一位,第二种为将n减一再右边移动一位,所以可以找到一种操作:每一次看n的最后两位,如果是11做第二种操作,这样就除去了最后一位,如果是01做第一种操作(不能做第二种操作,因为过程中不能出现偶数)。n的最大是1e9,最多30位,一定符合要求。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<iomanip>
#include<list>
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(),(x).end()
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const db pi=acos(-1.0);
const int N=40,M=2*N;
int a[N],b[N];
inline void solve()
{int n;cin>>n;if(n&1){int len=0,sz=0;while(n){a[++len]=n&1;n>>=1;}cout<<len-1<<endl;rep(i,1,len){if(a[i+1]) b[++sz]=2;else b[++sz]=1,a[i+1]=1; }per(i,sz,0) cout<<b[i]<<" ";cout<<endl;}else cout<<-1<<endl;
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int _=1;cin>>_;while(_--){solve();}return 0;
}

C. Make It Permutation

题意:

给定一个序列,可以进行两种操作,删除一个元素,花费为c,添加一个元素,花费为d,求使序列变为一个非空排列的最小花费。

思路:

因为排列不会存在重复元素,遇到重复元素一定要删除。将处理后的数组排序,考虑构造出1~a[i]的排列,删除后面的元素的花费,所有情况取最小值。注意将数组删除为空再补1的情况也要算。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<iomanip>
#include<list>
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(),(x).end()
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const db pi=acos(-1.0);
const int N=1e5+10,M=2*N;
int a[N],len;
inline void solve()
{len=0;set<int>st;int n,c,d,x;LL ans=0;cin>>n>>c>>d;rep(i,1,n+1){cin>>x;if(st.count(x)) ans+=c;else st.insert(x),a[++len]=x;}sort(a+1,a+1+len);LL mi=1e18,tot=0;rep(i,1,len+1){tot+=a[i]-a[i-1]-1;mi=min(mi,tot*d+(LL)(len-i)*c);}mi=min(mi,(LL)len*c+d);cout<<ans+mi<<endl;
}
int main()
{
//  #ifndef ONLINE_JUDGE
//      freopen("1.in","r",stdin);
//      freopen("1.out","w",stdout);
//  #endifios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int _=1;cin>>_;while(_--){solve();}return 0;
}

D. Climbing the Tree

题意:

一个蜗牛爬树,树的高度为h,蜗牛每天爬a,下降b(a>b),从高度0花费n天爬上高度h。现在不知道h的值,有两种事件,事件1是给定a,b,n,需判断当前事件是否和前面的冲突;时间2是给定a,b,判断是否能根据当前信息求出确切的n。

思路:

先寻找a,b,h,n的关系,因为最后一次距离顶端小于等于a可以直接上去,考虑爬高度h-a的情况,显然需要天,最后再花一天爬上h,总天数为

对于事件1,有:

于是可以根据a,b,n的值算出h的下界和上界,分别用lh和rh表示:

将lh和rh和前面的取交集,如果为空说明不合法,否则合法。

对于事件2,根据当前lh和rh可以根据上式计算出n,n唯一则说明有解,否则无解。

注意h<=a,n=1的边界情况。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<iomanip>
#include<list>
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(),(x).end()
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const db pi=acos(-1.0);
const int N=1e5+10,M=2*N;
int n;
void cal(int a,int b,LL &lh,LL &rh)
{if(n==1){lh=1,rh=a;return;}LL t=1ll*(n-2)*(a-b)+a;lh=t+1,rh=t+a-b;
}
LL calc(int a,int b,LL h)
{if(h<=a) return 1;LL res=(h-a)/(a-b);if((h-a)%(a-b)) res+=2;else res+=1;return res;
}
inline void solve()
{LL lh=-1,rh=1e18;int q;cin>>q;rep(_,0,q){int op,a,b;cin>>op>>a>>b;if(op==1){cin>>n;if(_){LL l,r;cal(a,b,l,r);if(l>rh||r<lh) cout<<0<<" ";else cout<<1<<" ",lh=max(lh,l),rh=min(rh,r);}else{cout<<1<<" ";cal(a,b,lh,rh);}//cout<<lh<<" "<<rh<<endl;}else{if(lh==-1){cout<<-1<<" ";continue; }LL n1=calc(a,b,lh),n2=calc(a,b,rh);if(n1==n2) cout<<n1<<" ";else cout<<-1<<" ";}}cout<<endl;
}
int main()
{
//  #ifndef ONLINE_JUDGE
//      freopen("1.in","r",stdin);
//      freopen("1.out","w",stdout);
//  #endifios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int _=1;cin>>_;while(_--){solve();}return 0;
}

E. Monsters

题意:

给定一个n个点,m条边的无向无环图,每个点都有一个怪物对应一个危险值,能打败某个点的怪物当且仅当打败的怪物数大于等于危险值。开始选择一个点出发,可以通过一个点需要能打败该点的怪物,判断能否打败所有怪物。

n, m (1≤n,m≤2e5)

思路:

本题官方给出了最暴力的做法:找到每一个ai=0的点做扩散,每一次扩散判断是否能扩展到所有点。虽然直觉上会超时,但是可以证明这样做复杂度为O(n*log(n)*log(n))。

相比官方做法更容易想到用并查集维护连续可走的块。先将危险值从小到大排序,需要一个数组来记录一个集合是否被选择(是否走过),每一次扩散都将危险值大的点并到危险值小的点,维护集合大小,最后合法的结果是一定只有一个根节点。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<iomanip>
#include<list>
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(),(x).end()
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const db pi=acos(-1.0);
const int N=2e5+10,M=2*N;
pii p[N];
int h[N],e[M],ne[M],idx,s[N],d[N],ok[N],vis[N],sz[N];
void add(int a,int b)
{e[++idx]=b,ne[idx]=h[a],h[a]=idx;
}
int find(int x)
{if(x==s[x]) return s[x];return s[x]=find(s[x]);
}
inline void solve()
{idx=0;MEM(h,0);int n,m;cin>>n>>m;rep(i,1,n+1) cin>>p[i].fi,p[i].se=i,s[i]=i,ok[i]=0,vis[i]=0,sz[i]=1;sort(p+1,p+1+n);rep(i,0,m){int a,b;cin>>a>>b;add(a,b),add(b,a);}rep(_,1,n+1){int u=p[_].se;if(p[_].fi==0) ok[u]=1;vis[u]=1;for(int i=h[u];i;i=ne[i]){int v=e[i];if(!vis[v]) continue;u=find(u),v=find(v);if(sz[v]>=p[_].fi&&ok[v]) ok[u]=1;if(u!=v){sz[u]+=sz[v];s[v]=u;}}}if(!ok[find(1)]){cout<<"NO"<<endl;return;}rep(i,2,n+1) if(find(i)!=find(1)){cout<<"NO"<<endl;return;}cout<<"YES"<<endl;
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int _=1;cin>>_;while(_--){solve();}return 0;
}

E题补充说明:

几个数组代表的意义:

vis[i]: i在前面有没有走过,这个作用是保证在无向图中从危险值小的到危险值大的走。

ok[i]: i的块是否合法。

s[i]: 并查集i的根

sz[i]:i的块走过的个数,用于和危险值比较判断是否合法。

首先出发点一定是危险值尽量越小越好,我们考虑从危险值小的点走向危险值大的点,将所有点按照危险值小的到危险值大的排序。然后枚举,比如我们枚举到了u,然后遍历它的邻接点v,需要保证v是否前面遍历过(v的危险值小于等于u的危险值),第69行代码就是判断u这个点是否满足题目条件,最后将v并到u。

私信的一些问题:

Q1:为什么合并的时候不需要判断?

A1:因为这里用并查集只是为了维护一个点可以走到的点数,判断合法用ok数组另加判断。

Q2:并查集根节点代表什么?

A2:根节点为一个连通块危险值最大的点,它的ok的值代表了这个块是否合法。

Q3:为什么危险值为0的时候将ok的值置为1,危险值为1的时候为什么不可以。

A3:题目要求是当前打败的怪物数量大于等于当前点危险度,所以开始打败数量为0,当然危险值也是0。后面的判断也是当前走了的点大于等于危险值。

CodeTON Round 4 (Div. 1 + Div. 2, Rated, Prizes!)A~E相关推荐

  1. Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)

    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2) 题号 题目 知识点 A A Variety of Opera ...

  2. Deltix Round, Spring 2021 (open for everyone, rated, Div. 1 + Div. 2)

    Deltix Round, Spring 2021 (open for everyone, rated, Div. 1 + Div. 2) 题号 题目 知识点 A Game of Life B Lor ...

  3. Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)切题报告(A-B题)

    这是我第二次参加CF比赛,也是第一次写博客,写得不好,望各位大佬海涵. A. Single Wildcard Pattern Matching 原题链接 这道题,这是难到让人无法直视,太水了. 题目大 ...

  4. [区间记忆化dp入门][Bribe the Prisoners SPOJ - GCJ1C09C][Codeforces Round #505D (rated, Div. 1 + Div. 2, ba]

    Bribe the Prisoners SPOJ - GCJ1C09C 作为这类题代表,f[i][j]代表第i点到第j点单独处理的最值 这题关键:释放某个囚犯后,就把囚犯分成两段,两段互相独立 这类d ...

  5. Codeforces Round #586 (Div. 1 + Div. 2) B. Multiplication Table 思维 + 公式

    传送门 文章目录 题意: 思路: 题意: 给你一个n∗nn*nn∗n的矩阵,每个位置由ai∗aja_i*a_jai​∗aj​得来,主对角线为000,让你求出来aia_iai​. n≤1e3n\le1e ...

  6. Codeforces Round #586 (Div. 1 + Div. 2) D. Alex and Julian 数学 + 思维

    传送门 文章目录 题意: 思路: 题意: 给你一个无限个点的坐标轴,一个集合BBB,如果存在∣i−j∣=bk|i-j|=b_k∣i−j∣=bk​的话,那么i,ji,ji,j之间就连边.现在问你至少要从 ...

  7. Codeforces Round #733 (Div. 1 + Div. 2) E. Minimax 分情况讨论 + 思维

    传送门 文章目录 题意: 思路: 题意: 给你一个串,你可以随意安排这个串,使得这个串的每个前缀的kmpkmpkmp数组最大值最小,定义为f(a)f(a)f(a),并且字典序最小,输出安排之后的串. ...

  8. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) F. Bits And Pieces sosdp预处理超集

    传送门 文章目录 题意: 思路: 题意: n≤1e6,ai≤2e6n\le1e6,a_i\le2e6n≤1e6,ai​≤2e6 思路: 由于(aj&ak)(a_j \And a_k)(aj​& ...

  9. Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated) D. Kuroni and the Celebration 交互 + 思维

    传送门 文章目录 题意: 思路: 题意: 给你一颗树,每次可以询问两个点的lcalcalca,询问次数不能超过⌊n2⌋\left \lfloor \frac{n}{2} \right \rfloor⌊ ...

最新文章

  1. 关于StartCoroutine的简单线程使用
  2. Redhat 图形模式与命令行模式的切换
  3. MCS-51单片机的指令时序
  4. java泛型学习一:解惑继承
  5. c调python_py_initialize:C调Python出错 是初始化错误?
  6. 单片机控制灯光亮度c语言程序,基于51单片机控制LED灯光亮度并报警
  7. 自动生成网络拓扑图开源_电信网络拓扑图自动布局之总线
  8. OpenCV算法精解1--OpenCV中C++基本操作1
  9. 48-Elasticsearch-2(DSL查询_搜索结果处理_RestClient查询文档)
  10. 微信扫一扫(wx.scanQRCode)功能新手可能遇到的问题
  11. TA 认识 unity shader最基本的代码结构与书写01
  12. 自动取款机取款属于计算机应用,在自动取款机前取款时应该注意什么?
  13. 供应ACA-PEG-SH,Acrylamide-PEG-Thiol,用于制备PEG水凝胶
  14. php生成sitemap.xml地图文件
  15. 计算机组装与维护校本教材,《计算机组装及维护》校本教材.pdf
  16. python改文件名_python实现批量修改文件名代码
  17. 使用贝壳采集器:中国农业信息网 数据采集
  18. 小米路由器 php7,小米路由器好不好用?看完这个评测你就懂了!
  19. Linux文件常用编辑方法
  20. 骁龙8gen2和苹果A16哪个强

热门文章

  1. 酒吧运营你要知道的:制订方案
  2. Qt pushbutton按钮常用方法及技巧总结
  3. AlphaControls 控件Delphi使用
  4. android 返回键 键盘,关于Android返回键关闭键盘和返回问题...求大神ING~
  5. --django--
  6. 【数字图像处理2.1 】频率域中的 高通滤波 和 低通滤波 Python+Opencv+Numpy
  7. 数字图像处理:实验六 图像分割
  8. Apache的order、allow、deny
  9. 云计算与大数据概论题库
  10. 转:SOHO小报网被关,请大家从爱护的愿望出发