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 & ...
随机推荐
- Python之读取用户指令和格式化打印
Python之读取用户指令和格式化打印 一.读取用户指令 当你的程序要接收用户输入的指令时,可以用input函数: name = input("请输入你的名字:") print(& ...
- 章节十六、5-TestNG高级功能--Part2
一.测试用例的依赖关系--->(dependsOnMethods = {"依赖方法名"}) 1.在实现自动化的过程中,有些测试用例必须在其它测试用例执行之后才能运行,两者之间 ...
- 剑指Offer(二十六):二叉搜索树与双向链表
剑指Offer(二十六):二叉搜索树与双向链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...
- 关于工作流引擎ccflow待办分类 研究与技术实现
关于工作流引擎待办分类 研究与技术实现 关键字:工作流引擎 BPM系统 待办类型 名词:待办 概要介绍:待办就是当前的登录人员要处理的工作,在工作流程里面的节点类型不同,业务场景不同,我们把待办分为如 ...
- Team Train Recorder
2014-2015 Petrozavodsk Winter Training Camp, Contest.58 (Makoto rng_58 Soejima contest) contest link ...
- HDU 5126 stars 4维偏序, CDQ套CDQ
题目传送门 题意:在一个星空中,按着时间会出现一些点,现在john想知道,在某个时间内有多少个星星是的坐标是满足条件的.(x1<=x<=x2, y1 <= y <= y2, z ...
- d3.js 制作简单的贪吃蛇
d3.js是一个不错的可视化框架,同时对于操作dom也是十分方便的.今天我们使用d3.js配合es6的类来制作一个童年小游戏–贪吃蛇.话不多说先上图片. 1. js snaker类 class Sna ...
- 【LeetCode】[0001] 【两数之和】
题目描述 思路分析 Java代码 代码链接 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标.你可以假设每种输入只会对 ...
- Sublime配置Python & sublime操作
前言 前几天我发了一个配置C++的博客,今天再给大家掏一掏Python如何配置.但是主要是操作,文件并没有很多. 正文 文件地址:python 提取码:3gb7 先全部解压,sublime就按照上面说 ...
- docker java环境 直接做成镜像 跑自己的java包
yum install docker #基于阿里源 可以直接下载 systemctl restart docker ifconfig #出现 docker0 说明环境部署成功 docker ver ...