长乐国庆集训Day5-2
T1 彩虹
题目
【题目描述】
Mr.Raju和他的一个大家庭外出度假,他们想要乘着彩虹欣赏周围的景色,但是这样最会有一些问题。
在他们家族中,如果一个人想要骑上彩虹,那么他喜欢的所有人和喜欢他的所有人都必须一同骑上彩虹。如果一个人没有喜欢的人,也没有人喜欢他,那么他也可以乘上彩虹。
你被请来解决这个难题,我们会提供给你家族所有成员的体重,以及每个人喜欢的人的列表,同样给出的还有彩虹能承受的总重量,你需要计算出在以上条件下彩虹所能承载的最多人数。
为了方便描述,所有的家庭成员都被标号,从1到n。
【输入格式】
有多组数据,每组数据之间有一空行。
对于每一组数据,第一行为整数n(1≤n≤1000)和c(0≤c≤1000),n表示家庭成员的总人数,c表示彩虹的承载量。
第二行为n个数为1到n个家庭成员的体重(体重是1000以内的正整数)。
接下来n行,每行第一个数k[i]表示第i个人有多少喜欢的人,接下来k[i]个整数为他喜欢的人的编号。
当n=0,c=0是表示数据结束。保证数据组数不超过3。
【输出格式】
对于每一组数据,输出可以同时骑彩虹的最大人数。(输出的每个答案之间不要空行)。
【输入样例】
【输出样例】
【数据规模】
对于20%的数据:n≤8;
对于100%的数据:n,c≤1000。
解析
先用并查集将每个人与其喜欢的人合并起来,计算他们的总重量与总人数。
再跑一遍01背包即可。
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
const int N=;
int n,C,a[N],b[N],c[N],fa[N],f[N],maxn;
int get(int x)
{
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
int main()
{
//freopen("rainbow.in","r",stdin);
//freopen("rainbow.out","w",stdout);
while()
{
n=read(),C=read(),maxn=;
if(n==&&C==) break;
memset(f,,sizeof(f));
for(int i=;i<=n;i++) a[i]=read(),b[i]=,c[i]=,fa[i]=i;
for(int i=;i<=n;i++)
{
int k=read();
for(int j=;j<=k;j++)
{
int x=read();
fa[get(i)]=get(x);
}
}
for(int i=;i<=n;i++)
{
int temp=get(i);
b[temp]+=a[i],c[temp]++;
}
for(int i=;i<=n;i++)
if(b[i]!=)
for(int j=C;j>=b[i];j--) f[j]=max(f[j],f[j-b[i]]+c[i]);
for(int i=;i<=C;i++) maxn=max(maxn,f[i]);
cout<<maxn<<endl;
}
return ;
}
T2 红十字
题目
【题目描述】
通往藏宝库的通道打开了,走下一段长长的楼梯,钻过一条矮矮的地道,你和小可可终于来到了藏宝库的门前。随之而来的就是最后一个挑战,只要能打开宝库的门,里面的宝藏就是你们的了。
宝库的门依然是通过机关打开,这个门很奇怪,是一个正方形,被划分成许多大小一致的正方形的小方格,这些方格不是红色就是白色,猛看上去这些方格组成了许多红十字状的标志。根据藏宝图记载,只要找到门上最大的红十字,按下它中心的方格,宝库的门就能打开了。
红十字标志也是一个正方形,边长为(2k+1)*(2k+1),其中k为非负整数。它的四条边与门的边平行,而且恰由门上的(2k+1)*(2k+1)个小方格组成。这里,红十字标志是以白色为底色,红色为十字的颜色。假设用1表示红色,用0表示白色。对应到计算机处理的数据中,就是除了正中列与正中行全为1外,其余方格均为0。
以下是几种不同大小的标志:
1*1:
1
3*3
010
111
010
5*5
00100
00100
11111
00100
00100
小可可被这个机关难到了,现在只有靠你了,请你帮助他在这个门上找到一个最大的红十字标志,输出它的边长即可。
【输入格式】
本题输入量巨大,推荐使用以下输入方法:
scanf("%d\n", &n);
for (i = 1; i<= n; i++) scanf("%s", s[i] + 1);
for (i = 1; i<= n; i++)
for (j = 1; j <= n; j++)
a[i][j] = s[i][j] - '0';
其中n是宝库的门的边长,s是字符数组,a[i][j]是第i行第j列的数值。
【输出格式】
对于每个询问输出一行表示答案。
【输入样例】
【输出样例】
【数据规模】
对于30%的数据,n≤100。
对于50%的数据,n≤500。
对于100%的数据,n≤2000。
解析
用sum纪录子矩阵的值。
对于以(x,y)为中心且长度为k的矩阵,如果是红十字,那么以(x,y)为中心且长度为k-2(k>=3)的矩阵必然也是红十字。
所以可以枚举红十字的中心,求出以(x,y)为中心的最大红十字的边长,具体可以用二分实现。
Code
#include<bits/stdc++.h>
using namespace std;
const int N=;
int n,a[N][N],sum[N][N],ans;
char s[N][N];
int dfs(int lx,int ly,int rx,int ry)
{
return sum[rx][ry]+sum[lx-][ly-]-sum[lx-][ry]-sum[rx][ly-];
}
int main()
{
scanf("%d\n",&n);
for(int i=;i<=n;i++) scanf("%s",s[i]+);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) a[i][j]=s[i][j]-'',sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+a[i][j];
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(a[i][j])
{
int l=,r=min(min(i,j),min(n-i+,n-j+)),cnt=;
while(l<=r)
{
int mid=(l+r)>>;
if(dfs(i-mid+,j,i+mid-,j)==mid*-&&dfs(i,j-mid+,i,j+mid-)==mid*-&&dfs(i-mid+,j-mid+,i+mid-,j+mid-)==mid*-) l=mid+,cnt=mid;
else r=mid-;
}
ans=max(ans,cnt*-);
}
printf("%d",ans);
return ;
}
T3 柱状图
题目
【题目描述】
在统计学中,柱状图是用来描述事件发生频率的一种图形语言,它是一种锯齿形的多边形,可以看做是一些长方形排列而成的。这些长方形的底边同为一个单位长度,但它们有不同的高度。对于给定的长方形,某些排列会使组成的多边形达到周长最长。你的任务是找出最长的周长以及构成最长周长的可能排列总数。
在图(a)中,组成多边形的长方形高度分别为{1,2,3,4},它的周长为16个单位长度。在图(b)中,组成多边形的长方形高度分别为{3,1,2,4},它的周长为20个单位长度。
【输入格式】
输入文件包含多组数据。
每组数据第一行为一个整数n (2≤n≤15),描述有一共有多少个长方形。第二行为n个整数,表示n个长方形的高。
当n=0 时,表示输入数据结束。保证数据组数不超过16。
【输出格式】
对于每组数据,输出一个整数表示答案。
【输入样例】
【输出样例】
【数据规模】
解析
不难发现,这题其实是全排列。
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int n,a[],ans=,tot,f[];
long long sum;
int main()
{
n=read(),f[]=;
for(int i=;i<=;i++) f[i]=f[i-]*i;
while(n)
{
tot=n*,ans=;
for(int i=;i<=n;i++) a[i]=read(),tot+=a[i]*;
sort(a+,a++n);
if(n%==)
{
for(int i=;i<=(n-)/;i++) ans+=a[i]*;
sum=f[n/+]*f[n/];
}
else
{
for(int i=;i<=n/-;i++) ans+=a[i]*;
ans+=a[n/]*,sum=f[n/-]*f[n/]*n;
}
cout<<tot-ans<<" "<<sum<<endl;
n=read();
}
return ;
}
T4 最长公共子序列
题目
【题目描述】
给定两个长度为5n的序列A,B。保证1~n这n个数在A,B中分别出现5次。求A,B最长公共子序列。
【输入格式】
第一行一个正整数n。
接下来两行,每行5n个正整数,表示序列A,B。
【输出格式】
输出一个整数,最长公共子序列的长度。
【输入样例】
【输出样例】
【数据规模】
对于30%的数据,n≤10。
对于60%的数据,n≤1000。
对于100%的数据,n≤20000。
解析
一下来自于出题人的题解。
注意1~n这n个数分别在A与B中出现5次。
枚举i,并维护f[j]表示A[1...i]和B[1...j]的最长公共子序列,且以B[j]为结尾。
对于每个x,用二维数组存下x在B中的所有位置,再枚举A[i]在B中的所有位置k。
此时,所有f[j]都是A[1...i-1]和B[1...j]的最长公共子序列。
令g[k]=max(f[1]~f[k-1])+1,即g[k]为A[1...i]和B[1...k]的最长公共子序列。
若B[j]!=A[i],则g[j]=f[j],即f[j]不改动。
所以只需做单点修改,并求前缀最大值,具体可以用树状数组维护f[j]的前缀最大值。
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
inline int read()
{
int num=;
char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num;
}
const int N=2e4+;
int n,a[N*],b[N*],c[N*],d[];
vector<int> g[N*];
void change(int x,int y)
{
for(int i=x;i<=n*;i+=i&-i) c[i]=max(c[i],y);
}
int ask(int x)
{
int ans=;
for(int i=x;i;i-=i&-i) ans=max(ans,c[i]);
return ans;
}
int main()
{
n=read();
for(int i=;i<=n*;i++) a[i]=read();
for(int i=;i<=n*;i++) b[i]=read(),g[b[i]].push_back(i);
for(int i=;i<=n*;i++)
{
for(int j=;j<=;j++)
{
int x=g[a[i]][j];
d[j]=ask(x-);
}
for(int j=;j<=;j++)
{
int x=g[a[i]][j];
change(x,d[j]+);
}
}
cout<<ask(n*);
return ;
}
长乐国庆集训Day5-2的更多相关文章
- 长乐国庆集训Day5
T1 方阵 题目 [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑是有一定规律的.兵马俑阵总共有n ...
- 牛客国庆集训day5 B 电音之王 (大数乘模)
链接:https://www.nowcoder.com/acm/contest/205/B来源:牛客网 题目描述 终于活成了自己讨厌的样子. 听说多听电音能加快程序运行的速度. 定义一个数列,告诉你a ...
- 牛客国庆集训day5 G 贵族用户 (模拟)
链接:https://www.nowcoder.com/acm/contest/205/G来源:牛客网 题目描述 终于活成了自己讨厌的样子. 充钱能让你变得更强. 在暖婊这个游戏里面,如果你充了x元钱 ...
- 长乐国庆集训Day4
T1 一道数论神题 题目 [题目描述] LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删 ...
- 长乐国庆集训Day3
T1 动态逆序对 题目 [题目描述] 给出一个长度为n的排列a(1~n这n个数在数列中各出现1次).每次交换两个数,求逆序对数%2的结果. 逆序对:对于两个数a[i],a[j](i<j),若a[ ...
- 长乐国庆集训Day2
T1 连珠风暴 题目 [题目描述] 给定M种颜色的珠子,每种颜色珠子的个数均不限,将这些珠子做成长度为N的项链. 问能做成多少种不重复的项链.两条项链相同,当且仅当两条项链通过旋转或是翻转后能重合在一 ...
- 长乐国庆集训Day1
T1 统计数字 题目 [题目描述] 设 S(N ) 表示 N 的各位数字之和,如 S(484) = 4+8+4 = 16, S(22) = 2+2 = 4. 如果一个正整数满足 S(x*x) = S( ...
- 2019牛客国庆集训派对day5
2019牛客国庆集训派对day5 I.Strange Prime 题意 \(P=1e10+19\),求\(\sum x[i] mod P = 0\)的方案数,其中\(0 \leq x[i] < ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
随机推荐
- SQL注入学习
本次实验环境用的是Xampp,搭建的sqli-labs 配置环境: 下载路径https://github.com/Audi-1/sqli-labs,下载源代码,将解压好的文件夹放在xampp\htdo ...
- ES6基础入门之let、const
作者 | Jeskson来源 | 达达前端小酒馆 01 首先呢?欢迎大家来学习ES6入门基础let,const的基础知识内容.初始ECMA Script6. ESMAScript与JavaScript ...
- TensorFlow安装笔记(CPU版)
新电脑配环境又出了问题. 先是装了最新版anaconda,python3.7的版本.——2019.10.21 然后conda install TensorFlow,conda install kera ...
- mac 搭建Java Spring boot 环境(idea)
首先安装插件 安装下面的这个插件 然后重启idea,新建工程 选择新建 Springboot 框架 改写项目名称 选择类型 设置工程名称 删除多余的文件 编译工程 然后运行 1. 2. 参考: htt ...
- linux jar/war包 后台运行
1. 基础版,当前ssh窗口锁定,按CTRL+C打断程序运行:或关闭窗口,程序退出 java -jar flowable-modeler.war 2. 改进版,当前ssh窗口不锁定,窗口关闭时,程序终 ...
- eclipse 如何将文件编辑器窗口的背景填充为背景图片?
1.情景展示 文件编辑窗口的背景默认为白色. 我们知道,对于整日面对电脑的程序员来说,白色容易造成眼疲劳,而且对于眼睛的伤害比较大. 所以,eclipse添加了黑色主题. 切换成黑色主题 改变 ...
- Android开发:文本控件详解——RadioButton和CheckBox(一)基本属性
一.RadioButton和RadioGroup: RadioButton是单个的圆形单选框,而RadioGroup是可以容纳多个RadioButton存在的容器,因此RadioButton和Radi ...
- FNV哈希算法(转)
由来:FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的,最早在1991年提出. 特点和用途 ...
- intellij idea远程调试
有时候发布后的包不得不进行debug,但是又不方便本地开发环境直接debug模拟,所以不得不需要远程debug. 启动参数 首先在服务端使用JVM的-Xdebug参数启动Jar包. java -Xde ...
- 笔记-Git:资源列表
ylbtech-笔记-Git:资源列表 Yahoo!, Facebook, Salesforce, Microsoft, Twitter, Deutsche Telekom, Intuit, Mozi ...