传送门

A. Divide it!

•题意

给定一个数n, 每次可以进行下列一种操作

1.如果n可以被2整除,用n/2代替n

2.如果n可以被3整除,用2n/3代替n

3.如果n可以被5整除,用4n/5代替n

如果可以经过上述操作使得 n 变为 1,输出最小操作次数,反之,输出-1;

•思路

n/2 < 2n/3 < 4n/5 要想操作次数最少,优先操作 1 > 2 > 3;

•代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[];
int main()
{
int t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
int flag=;
int Count=;
while(n>)
{
if(n%==)//
{
n/=;
Count++;
}
else if(n%==)//
{
n=n/*;
Count++;
}
else if(n%==)//
{
n=n/*;
Count++;
}
else//不能被整除,即经过操作不能变为1
{
flag=;
break;
}
}
if(flag)
cout<<-<<endl;
else
cout<<Count<<endl;
}
}

B. Merge it!

•题意

给你一个包含 n 个数的序列 a;

  定义序列 a 上的一个操作:合并任意两个元素;

  你可以对序列 a 执行上述操作任意次,求操作后的序列最多有多少元素可以被 3 整除;

•思路

对于任意一个数x

1.如果x是3的倍数,x%3==0

如果x不是3的倍数

2.如果x+1是3的倍数,x%3==1,3*x%x==0

3.如果x+2是3的倍数,x%3==2,3*x%x==0

如果想尽可能多的是三的倍数:

首先加x%3==0的x的个数,这样只使用一个数

其次2和3相加正好是3的倍数,这样只使用两个数

最后还剩下2或者3,则自身结合,这样是使用三个数

•代码

#include<bits/stdc++.h>
using namespace std;
int a[];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int zero=,one=,two=;//分别记录x%3为0,1,2的个数
for(int i=;i<n;i++)
{
cin>>a[i];
a[i]%=;
if(a[i]==)
zero++;
else if(a[i]==)
one++;
else
two++;
}
// cout<<zero<<' '<<one<<' '<<two<<endl;
if(one>=two)
cout<<zero+two+(one-two)/<<endl;
else
cout<<zero+one+(two-one)/<<endl;
}
}

C. Lose it!

题意

  给你一个包含 n 个整数的序列 a和good序列{4,8,15,16,23,42};

  在删去 x 个数后,使得序列 a 可以划分成 (n-x) / 6 个 "good" 序列;

  求 x 的最小值;

题解

  求出序列 a 最多有多少个 "good" 序列(假设有 ans 个),需要删去的个数就是 n-6×ans;

•代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=; vector<int> p[];
int s[maxn];
int t[]={,,,,,,};
int ans=;//一共有ans个good串
int a[];//记录使用后的每个字母的最后一个位置,即这个字母到达的最远的位置
//后面再找这个字母时,从这个位置的下一个开始找,可以减少查找量
int main()
{
int n;
cin>>n;
for(int i=;i<=n;i++)
{
cin>>s[i];
p[s[i]].push_back(i);//预处理s串每个good数的位置
}
int cur=;
int flag;
for(int i=;i<=;i++)
{
flag=;
for(int j=a[t[i]];j<p[t[i]].size();j++)
{
flag=;
if(p[t[i]][j]>cur)//在s串中找x出现的位置 >cur 的第一个位置,有点贪心的感jio
{
cur=p[t[i]][j];//更新cur
a[t[i]]=j+;//记录之前x到达的最远位置j,后面从j+1开始找
flag=;
break;
}
}
if(!flag)
break;
if(cur>n)
break;
if(i==)//找完一次,再从第一个good数找下一次
{
ans++;
cur=;
i=;
}
}
cout<<n-ans*<<endl;
}

D. Recover it!

•题意

有一个数组a和一个数组b,其中b是这样组成的

①b中包含a中所有的数

②对于a中的数,如果ai是素数,那么在b中添加第ai个素数

  如果ai是合数,那么在b中添加ai的最大约数(除ai外的)

如果a中有n个数,那么b中包含如上的2*n个数

现给出b中的所有数,求a中的所有数

•思路

对于b中的数 ,我们可以考虑从大到小排序,

①如果最大的这个数是合数的话,那么他一定是a中的数,因为在b中添加的是比ai

小的最大约数
②如果是素数的话,那么他一定是被添加到b中的数,也就是一定不是a中的数,而他所对应的这个素数的位置才是a中的数

•代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+;
const int mm=; int Mark[mm+];
int prime[maxn]; int index;
void Prime()
{
memset(Mark,,sizeof(Mark));
for(int i=;index<=;i++)
{
if(Mark[i]==)
prime[index++]=i;
for(int j=;j<index&&prime[j]*i<=mm;j++)
{
Mark[i*prime[j]]=;
if(i%prime[j]==)
break;
}
}
} map<int,int> mp;//用map存便于找是减少数量
int a[maxn],b[*maxn];
int main()
{
Prime();
int n;
cin>>n; for(int i=;i<*n;i++)
{
cin>>b[i];
mp[b[i]]++;
}
int cur=;
sort(b,b+*n);
for(int i=*n-;i>=;i--)
{
if(!mp[b[i]])
continue;
if(cur>n)
break;
if(Mark[b[i]])//合数
{
a[cur++]=b[i];//加到a数组中
for(int j=;;j++)//找最大的约数
{
if(b[i]%j==)
{
mp[b[i]/j]--;//删去这个约数
break;
}
}
}
else//素数
{
int p=+lower_bound(prime,prime+index,b[i])-prime;//这个素数的位置
a[cur++]=p;//加到a数组中
mp[p]--;//删去这个代表位置的素数
}
mp[b[i]]--;//删去已经找完的这个数
}
for(int i=;i<n;i++)
cout<<a[i]<<' ';
}

用map存是从李先生那偷过来的(QWQ)


E. Cover it!

题意

从含有 n 个点,m 条边的无向图中取出 x 个点,这 x 个点需满足:

  ① x ≤ n/2;

  ②剩余的点至少与这 x 个点中的一个点有连边;

  输出满足条件的这 x 个点;

题解

李先生说这是二部图裸题,据他说,突然想到我们老班离散课上讲的知识,可能是我没听讲???(还不是因为太菜惹

找出集合 U 和集合 V,输出 |U| 和 |V| 中元素个数最少的集合;

以任意一个点开始,加入把他涂成红色,那和他相连的点涂成绿色,和这个点相邻的量再涂成红色....以此

就分成了两个集合,输出点数较少的那个集合

•代码

bfs涂色

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int x,y;
int cntx,cnty;
struct Edge
{
int u;
int v;
int nex;
}edge[*maxn];
struct Data//涂色
{
int v;
int col;
};
int head[maxn],vis[maxn],cnt;
int a[maxn],b[maxn];//0:红色,b:绿色 a[]为0集合,b[]为1集合
void add(int u,int v)
{
edge[++cnt].u=u;
edge[cnt].v=v;
edge[cnt].nex=head[u];
head[u]=cnt;
}
queue<Data>q;
void paint()
{
while(!q.empty())//bfs涂色
{
Data tmp=q.front();
int u=tmp.v;//这个点涂色
q.pop();
for(int i=head[u];i;i=edge[i].nex)
{
int v=edge[i].v;
if(!vis[v])
{
vis[v]=;
q.push(Data{v,!tmp.col});//和他相连的点涂相反的颜色
if(tmp.col)//分在两个集合里
a[++cntx]=v;
else
b[++cnty]=v;
}
}
}
} int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++)
vis[i]=,head[i]=,a[i]=,b[i]=;
cnt=;
cntx=,cnty=; for(int i=;i<m;i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
} while(!q.empty())
q.pop();
q.push(Data{x,});//以一个点开始
a[++cntx]=x;
vis[x]=;
paint(); if(cntx<=n/)
{
cout<<cntx<<endl;
for(int i=;i<=cntx;i++)
cout<<a[i]<<' ';
}
else
{
cout<<cnty<<endl;
for(int i=;i<=cnty;i++)
cout<<b[i]<<' ';
}
cout<<endl;
}
}

dfs涂色

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+;
struct Edge
{
int v;
int nex;
}edge[*maxn];
int head[maxn*];
int cnt;
void add(int u,int v)
{
edge[++cnt]=Edge{v,head[u]};
head[u]=cnt;
}
int col[maxn*];//染色数组分为0,1两组代表红、绿 void paint(int u,int flag)//dfs涂色
{
col[u]=flag;//u点染成flag色
for(int i=head[u];i;i=edge[i].nex)//下一个未染色的点染成和他相反的颜色
{
int v=edge[i].v;
if(col[v]==-)
paint(v,!flag);
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cnt=;
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++)
head[i]=,col[i]=-;
int x,y;
for(int i=;i<m;i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
}
paint(x,);
int ans=;
for(int i=;i<=n;i++)
if(col[i])
ans++;
if(ans>n/)
{
cout<<n-ans<<endl;
for(int i=;i<=n;i++)
if(!col[i])
cout<<i<<' ';
}
else
{
cout<<ans<<endl;
for(int i=;i<=n;i++)
if(col[i])
cout<<i<<' ';
}
cout<<endl;
}
}

ps.偷偷学了一下李先生的链式前向星加边,比我以前的方法省了好多代码^(*-.-*)^

Codeforces Round #565 (Div. 3)的更多相关文章

  1. Codeforces Round #565 (Div. 3) B. Merge it!

    链接: https://codeforces.com/contest/1176/problem/B 题意: You are given an array a consisting of n integ ...

  2. Codeforces Round #565 (Div. 3) A. Divide it!

    链接: https://codeforces.com/contest/1176/problem/A 题意: You are given an integer n. You can perform an ...

  3. Codeforces Round #565 (Div. 3) C. Lose it!

    链接: https://codeforces.com/contest/1176/problem/C 题意: You are given an array a consisting of n integ ...

  4. Codeforces Round #565 (Div. 3) B

    B. Merge it! 题目链接:http://codeforces.com/contest/1176/problem/B 题目 You are given an array a consistin ...

  5. Codeforces Round #565 (Div. 3) A

    A. Divide it! 题目链接:http://codeforces.com/contest/1176/problem/A 题目 You are given an integer n You ca ...

  6. Codeforces Round #565 (Div. 3) F.Destroy it!

    题目地址:http://codeforces.com/contest/1176/problem/F 思路:其实就是一个01背包问题,只是添加了回合和每回合的01限制,和每当已用牌数到了10的倍数,那张 ...

  7. Codeforces Round #565 (Div. 3)--D. Recover it!--思维+欧拉筛

    D. Recover it! Authors guessed an array aa consisting of nn integers; each integer is not less than ...

  8. Codeforces Round #565 (Div. 3) C. Lose it! (思维)

    题意:给你一串只含\(4,8,15,16,23,42\)的序列,如果它满足长度是\(6\)的倍数并且有\(\frac {k}{6}\)个子序列是\([4,8,15,16,23,42]\),则定义它是好 ...

  9. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

随机推荐

  1. mpvue 开发小程序接口数据统一管理

    mpvue项目里做API与数据分离统一管理 小程序里请求数据接口使用wx:request,因为考虑项目比较大,最好把wx:request封装起来,统一使用管理 utils.js 配置开发环境和线上环境 ...

  2. .NET开发框架(二)-框架功能简述

    若视频播放不了,请点击 这里查看 本框架为响应式SPA框架,支持PC与手机端的屏幕自适应.手机展示效果视频在文章末尾查看. 框架入口地址:http://letyouknow.net/ 1.框架登录界面 ...

  3. Spring-Boot + MyBatis-Plus 踩坑记录

    这两天在学SpringBoot+MyBatis的开发,配置开发环境和DEMO的过程中踩了很多坑,在这里记录一下. 我的开发环境是idea + JDK 1.8.0.211. 首先展示一下demo的项目整 ...

  4. Redi缓存注意事项

    缓存使用的场景 在一个高频访问的应用系统中,每次用户的请求需要去存储中获取数据,会对数据库造成很大的压力.容易导致数据库的奔溃.所以才会出现缓存来分担一部分的数据库的压力. 具体会产生数据库访问压力的 ...

  5. 抽丝剥茧分析asyncio事件调度的核心原理

    先来看一下一个简单的例子 例1: async def foo(): print('enter foo ...') await bar() print('exit foo ...') async def ...

  6. 机器学习读书笔记(五)AdaBoost

    一.Boosting算法 .Boosting算法是一种把若干个分类器整合为一个分类器的方法,在boosting算法产生之前,还出现过两种比较重要的将多个分类器整合为一个分类器的方法,即boostrap ...

  7. HDU 6181:Two Paths(A* + SPFA)

    题目链接 题意 给出n个点m条边的无向图,求次短路. 思路 和 POJ 2449 类似,只不过大小要开成long long. #include <bits/stdc++.h> using ...

  8. BZOJ 1026:windy数(数位DP)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026 1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memor ...

  9. LSI 9211-8I阵列卡IR模式Update为IT模式操作步骤!

    以下是DOS系统环境下操作(也可以在windows.linux环境下,只要找到对应的tool就可以)相对应的tool官网可以下载 链接:https://www.broadcom.com/support ...

  10. 超哥的 LINUX 入门大纲

    前言 “Linux?听说是一个操作系统,好用吗?” “我也不知道呀,和windows有什么区别?我能在Linux上玩LOL吗” “别提了,我用过Linux,就是黑乎乎一个屏幕,鼠标也不能用,不停地的敲 ...