gym102346题解
B Buffoon
判断最大值是不是第一个数,签到题。
H Hour for a Run
输出\(n*m\)的\(10\%\)到\(90\%\),签到题,注意别用浮点数和ceil,有精度问题。
M Maratona Brasileira de Popcorn
题有点难读,就是给n个数,m个人,每人分一个连续段,每个数只能分给一个人,每人每秒最多把数字减k,问最少时间。
二分每一段的上界,贪心判断即可。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
int n,m,k,a[N];
bool check(int x){
int c=1;
int tmp=0;
for(int i=1;i<=n;i++){
if(a[i]>x){
return false;
}
if(tmp+a[i]<=x){
tmp+=a[i];
}else{
c++;
tmp=a[i];
}
}
return c<=m;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
int sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
int l=1,r=sum;
int ans=0;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)){
r=mid-1;
ans=mid;
}else{
l=mid+1;
}
}
printf("%d\n",(ans-1)/k+1);
return 0;
}
D Denouncing Mafia
题意相当于给定一棵树,找出k条链使得覆盖的点最多。
考虑贪心,每次肯定拿最长的一条链,然后拿走这条链后,树会变成一个森林,下一次再从这些树中取出最长链,再加入一些树
dfs一遍预处理出每个节点对应子树的最长链和删去最长链后得到的森林根节点,用一个优先队列贪心取即可。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+55;
vector<int> g[N];
int ld[N];
vector<int> ls[N];
int n,k,f;
struct node{
int u,w;
bool operator<(const node& rhs)const{
return w<rhs.w;
}
};
void dfs(int u){
int siz=g[u].size();
if(!siz){
ld[u]=1;
return;
}
int mx=0;
int k=0;
for(int i=0;i<siz;i++){
int v=g[u][i];
dfs(v);
if(ld[v]>mx){
mx=ld[v];
k=v;
}
}
ld[u]=mx+1;
for(int i=0;i<siz;i++){
int v=g[u][i];
if(v!=k){
ls[u].push_back(v);
}
}
int vs=ls[k].size();
for(int j=0;j<vs;j++){
ls[u].push_back(ls[k][j]);
}
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&k);
for(int i=2;i<=n;i++){
scanf("%d",&f);
g[f].push_back(i);
}
dfs(1);
priority_queue<node> pq;
pq.push({1,ld[1]});
int ans=0;
while(!pq.empty()){
auto t=pq.top();
int u=t.u;
int w=t.w;
pq.pop();
ans+=w;
k--;
if(!k){
break;
}
int siz=ls[u].size();
for(int i=0;i<siz;i++){
pq.push({ls[u][i],ld[ls[u][i]]});
}
}
printf("%d\n",ans);
return 0;
}
L Less Coin Tosses
题意本质就是长度为n的所有01串,0和1个数相同的可以匹配,找出不能匹配的01串个数。
先考虑枚举0(或者1)的个数,这样的串有\(C_n^i\)个,那么这些串的01个数显然相同,如果偶数,可以一一匹配,如果是奇数,答案加1。
所以本质就是求\(\sum_{i=1}^n C_n^i\%2\),打表找规律,发现有一个递归翻倍的常见套路。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll pw[115],f[115];
int cnt;
void init(){
pw[0]=1;
f[0]=pw[0]-1;
for(int i=1;i<=105;i++){
pw[i]=pw[i-1]*2;
f[i]=pw[i]-1;
if(pw[i]>(ll)1e18){
cnt=i;
break;
}
}
}
ll solve(int k,ll n){
if(k==1){
return 2ll;
}
ll mid=pw[k-1]/2;
if(n<=mid){
return solve(k-1,n);
}else{
return 2ll*solve(k-1,n-mid);
}
}
int main(){
init();
scanf("%lld",&n);
int k=lower_bound(f+1,f+1+cnt,n)-f;
ll ans=solve(k,n-f[k-1]);
printf("%lld\n",ans);
return 0;
}
G Getting Confidence
给定\(n*n\)的矩阵,每列选一个数且不能同一行,使得乘积最大。
- 做过类似套路的题目,将数求个对数,然后乘积最大就是和最大,然后网络流建图,限制每行每列,跑个最小费用最大流。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
const int INF=0x3f3f3f3f;
const double DINF=1.0*1e18;
const double eps=1e-8;
struct Edge{
int u,v,w;
double c;
int next;
}e[N];
int ns,n,mt[105][105];
int cnt,head[N];
void init(){
cnt=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w,double c){
e[cnt]=Edge{u,v,w,c,head[u]};
head[u]=cnt++;
e[cnt]=Edge{v,u,0,-c,head[v]};
head[v]=cnt++;
}
double d[N];
int inq[N],s,t,p[N],a[N];
bool bf(int &flow,double &cost){
for(int i=0;i<ns;i++){
d[i]=DINF;
inq[i]=0;
}
d[s]=0;
p[s]=0;
a[s]=INF;
queue<int> q;
q.push(s);
inq[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
inq[u]=false;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
int w=e[i].w;
double c=e[i].c;
if(w>0 && d[v]>d[u]+c){
d[v]=d[u]+c;
p[v]=i;
a[v]=min(a[u],w);
if(!inq[v]){
q.push(v);
inq[v]=1;
}
}
}
}
if(fabs(d[t]-DINF)<eps){
return 0;
}
flow+=a[t];
cost+=d[t]*a[t];
for(int u=t;u!=s;u=e[p[u]].u){
e[p[u]].w-=a[t];
e[p[u]^1].w+=a[t];
}
return 1;
}
void mcmf(int &flow,double &cost){
flow=0;
cost=0.0;
while(bf(flow,cost));
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&mt[i][j]);
}
}
ns=(n+2)*n+2;
s=0,t=ns-1;
init();
for(int i=1;i<=n;i++){
add(s,n*n+i,1,0.0);
}
for(int i=1;i<=n;i++){
add(n*n+n+i,t,1,0.0);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
add(n*n+i,(j-1)*n+i,1,0.0);
add((j-1)*n+i,n*n+n+j,1,-log10(mt[j][i]));
}
}
int flow=0;
double cost=0;
mcmf(flow,cost);
for(int i=n*n+1;i<=n*n+n;i++){
for(int j=head[i];j!=-1;j=e[j].next){
if(e[j].w==0){
printf("%d",(e[j].v-1)/n+1);
if(i==n*n+n){
printf("\n");
}else{
printf(" ");
}
break;
}
}
}
return 0;
}
J Jar of Water Game
题意不清的模拟题...还好队友什么牌都玩过
n个人,每个人有4张牌,初始指定第k个人有一张万能牌且从他开始,每次选一张出现次数最少的牌给下一个人,如果有万能牌且不是刚拿到,必须把万能牌给下一个人,如果有多个牌出现次数一样小,给那个值小的。
胜利的状态定义为手上有4张相同的牌,不能有万能牌,如果有多少胜利状态的人,即相同牌值小的胜利。
#include <bits/stdc++.h>
using namespace std;
int idx(char c){
if(c=='A'){
return 1;
}else if(c>='2' && c<='9'){
return c-'0';
}else if(c=='D'){
return 10;
}else if(c=='Q'){
return 11;
}else if(c=='J'){
return 12;
}else if(c=='K'){
return 13;
}else if(c=='X'){
return 14;
}
}
int n,k;
struct node{
int cnt[15];
int tm;
bool has;
}a[1005];
char s[10];
int win(){
int ans=0;
int res=0x3f3f3f3f;
for(int x=1;x<=n;x++){
int mx=0;
int mk=0;
for(int i=1;i<=13;i++){
mx=max(mx,a[x].cnt[i]);
if(a[x].cnt[i]>mx){
mx=a[x].cnt[i];
mk=i;
}
}
if(mx==4 && !a[x].has){
if(mk<res){
res=mk;
ans=x;
}
}
}
return ans;
}
int get(int x){
if(a[x].has && a[x].tm==1){
return 14;
}else{
if(a[x].has){
a[x].tm=1;
}
int mn=0x3f3f3f3f;
for(int i=1;i<=13;i++){
if(!a[x].cnt[i]){
#include <bits/stdc++.h>
using namespace std;
int idx(char c){
if(c=='A'){
return 1;
}else if(c>='2' && c<='9'){
return c-'0';
}else if(c=='D'){
return 10;
}else if(c=='Q'){
return 11;
}else if(c=='J'){
return 12;
}else if(c=='K'){
return 13;
}else if(c=='X'){
return 14;
}
}
int n,k;
struct node{
int cnt[15];
int tm;
bool has;
}a[1005];
char s[10];
int win(){
int ans=0;
int res=0x3f3f3f3f;
for(int x=1;x<=n;x++){
int mx=0;
int mk=0;
for(int i=1;i<=13;i++){
mx=max(mx,a[x].cnt[i]);
if(a[x].cnt[i]>mx){
mx=a[x].cnt[i];
mk=i;
}
}
if(mx==4 && !a[x].has){
if(mk<res){
res=mk;
ans=x;
}
}
}
return ans;
}
int get(int x){
if(a[x].has && a[x].tm==1){
return 14;
}else{
if(a[x].has){
a[x].tm=1;
}
int mn=0x3f3f3f3f;
for(int i=1;i<=13;i++){
if(!a[x].cnt[i]){
continue;
}
mn=min(mn,a[x].cnt[i]);
}
for(int i=1;i<=13;i++){
if(mn==a[x].cnt[i]){
return i;
}
}
}
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%s",s);
for(int j=0;j<4;j++){
int x=idx(s[j]);
a[i].cnt[x]++;
}
a[i].has=false;
a[i].tm=0;
}
a[k].has=true;
int cur=k;
while(true){
if(int w=win()){
printf("%d\n",w);
return 0;
}
int nex=get(cur);
int nt=cur%n+1;
a[cur].cnt[nex]--;
a[nt].cnt[nex]++;
if(nex==14){
a[cur].has=false;
a[cur].tm=0;
a[nt].has=true;
a[nt].tm=0;
}
cur=nt;
}
return 0;
}
continue;
}
mn=min(mn,a[x].cnt[i]);
}
for(int i=1;i<=13;i++){
if(mn==a[x].cnt[i]){
return i;
}
}
}
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%s",s);
for(int j=0;j<4;j++){
int x=idx(s[j]);
a[i].cnt[x]++;
}
a[i].has=false;
a[i].tm=0;
}
a[k].has=true;
int cur=k;
while(true){
if(int w=win()){
printf("%d\n",w);
return 0;
}
int nex=get(cur);
int nt=cur%n+1;
a[cur].cnt[nex]--;
a[nt].cnt[nex]++;
if(nex==14){
a[cur].has=false;
a[cur].tm=0;
a[nt].has=true;
a[nt].tm=0;
}
cur=nt;
}
return 0;
}
gym102346题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- SPI 机制-插件化扩展功能
SPI(Service Provider Interfaces),中文直译服务提供者接口,一种服务发现机制.可能很多人都不太熟悉这个机制,但是平常或多或少都用到了这个机制,比如我们使用 JDBC 连接 ...
- 操作系统-IO管理概述
IO管理概述 一.IO设备 IO设备管理是操作系统设计中最凌乱也最具挑战性的部分.由于它包含了很多领域的不同设备以及与设备相关的应用程序,因此很难有一个通用且一直的设计方案.所以在理解设备管理之前,应 ...
- C函数指针状态机实现
C函数指针状态机实现 有限状态机(finite state machine)简称FSM,表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.FSM是一种逻辑单元内部 ...
- net start mysql提示:服务名无效
1.win+R打开运行窗口,输入services.msc 2.在其中查看mysql的服务名,我的是MySQL55 3.以管理员身份打开cmd,输入net start MySQL55 出现下图,代表my ...
- HDU4578 线段树(区间更新 + 多种操作)和平方,立方
参考:https://www.cnblogs.com/H-Vking/p/4297973.html 题意: 虽然是比较裸的线段树,但是比较麻烦,并且有很多细节需要考虑,对着别人的ac代码debug了一 ...
- hdu 5887 Herbs Gathering (dfs+剪枝 or 超大01背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5887 题解:这题一看像是背包但是显然背包容量太大了所以可以考虑用dfs+剪枝,贪心得到的不 ...
- hihocoder #1609 : 数组分拆II(思维)
题目链接:http://hihocoder.com/problemset/problem/1609 题解:就先拿一个数组最多分成两部分来说吧 8 1 2 3 4 5 1 2 3 显然 输出时2 3 可 ...
- Dungeon Master POJ - 2251 [kuangbin带你飞]专题一 简单搜索
You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of un ...
- x86_64 Linux 运行时栈的字节对齐
前言 C语言的过程调用机制(即函数之间的调用)的一个关键特性(起始大多数编程语言也是如此)都是使用了栈数据结构提供的后进先出的内存管理原则.每一个函数的栈空间被称为栈帧,一个栈帧上包含了保存的寄存器. ...
- mysql之innodb存储引擎介绍
一.Innodb体系架构 1.1.后台线程 后台任务主要负责刷新内存中的数据,保证缓冲池的数据是最近的数据,此外还将修改的数据刷新到文件磁盘,保证在数据库发生异常的情况下Innodb能恢复到正常的运行 ...