2018"百度之星"程序设计大赛 - 资格赛 A/B/E/F
调查问卷
度度熊为了完成毕业论文,需要收集一些数据来支撑他的论据,于是设计了一份包含 mm 个问题的调查问卷,每个问题只有 'A' 和 'B' 两种选项。
将问卷散发出去之后,度度熊收到了 nn 份互不相同的问卷,在整理结果的时候,他发现可以只保留其中的一部分问题,使得这 nn 份问卷仍然是互不相同的。这里认为两张问卷是不同的,当且仅当存在至少一个被保留的问题在这两份问卷中的回答不同。
现在度度熊想知道,存在多少个问题集合,使得这 nn 份问卷在只保留这个集合的问题之后至少有 kk 对问卷是不同的。
第一行包含一个整数 TT,表示有 TT 组测试数据。
接下来依次描述 TT 组测试数据。对于每组测试数据:
第一行包含三个整数 nn,mm 和 kk,含义同题目描述。
接下来 nn 行,每行包含一个长度为 mm 的只包含 'A' 和 'B' 的字符串,表示这份问卷对每个问题的回答。
保证 1 \leq T \leq 1001≤T≤100,1 \leq n \leq 10^31≤n≤103,1 \leq m \leq 101≤m≤10,1 \leq k \leq 10^61≤k≤106,给定的 nn 份问卷互不相同。
对于每组测试数据,输出一行信息 "Case #x: y"(不含引号),其中 x 表示这是第 xx 组测试数据,y 表示满足条件的问题集合的个数,行末不要有多余空格。
2
2 2 1
AA
BB
2 2 2
AA
BB
Case #1: 3
Case #2: 0 注意到m很小,可以暴力枚举所有的子集然后判断不同的对数是否大于等于k。注意可能有多个人的问卷是一样的。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
int vis[];
char e[][];
int main(){
int t,n,q,m,i,j,cas=,k;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&k);
for(i=;i<n;++i) scanf("%s",e[i]);
int ans=,all=((<<m)-);
for(int i=;i<=all;++i){
int x=,y=;
memset(vis,,sizeof(vis));
for(int j=;j<n;++j){
x=;
for(int k=;k<m;++k){
if(i&(<<k)){
x<<=;
if(e[j][k]=='B') x|=;
}
}
vis[x]++;
}
LL ss=,tmp=;
for(int j=;ss<n;++j){
if(!vis[j]) continue;
tmp+=1LL*vis[j]*(n-ss-vis[j]);
ss+=vis[j];
}
if(tmp>=k)ans++;
}
printf("Case #%d: %d\n",++cas,ans);
}
return ;
}
子串查询
度度熊的字符串课堂开始了!要以像度度熊一样的天才为目标,努力奋斗哦!
为了检验你是否具备不听课的资质,度度熊准备了一个只包含大写英文字母的字符串 A[1,n] = a_1 a_2 \cdots a_nA[1,n]=a1a2⋯an,接下来他会向你提出 qq 个问题 (l,r)(l,r),你需要回答字符串 A[l,r] = a_l a_{l+1} \cdots a_rA[l,r]=alal+1⋯ar 内有多少个非空子串是 A[l,r]A[l,r] 的所有非空子串中字典序最小的。这里的非空子串是字符串中由至少一个位置连续的字符组成的子序列,两个子串是不同的当且仅当这两个子串内容不完全相同或者出现在不同的位置。
记 |S|∣S∣ 为字符串 SS 的长度,对于两个字符串 SS 和 TT ,定义 SS 的字典序比 TT 小,当且仅当存在非负整数 k(\leq \min(|S|,|T|))k(≤min(∣S∣,∣T∣)) 使得 SS 的前 kk 个字符与 TT 的前 kk 个字符对应相同,并且要么满足 |S| = k∣S∣=k 且 |T| > k∣T∣>k,要么满足 k < \min(|S|,|T|)k<min(∣S∣,∣T∣) 且 SS 的第 k+1k+1 个字符比 TT 的第 k+1k+1 个字符小。例如 "AA" 的字典序比 "AAA" 小,"AB" 的字典序比 "BA" 小。
第一行包含一个整数 TT,表示有 TT 组测试数据。
接下来依次描述 TT 组测试数据。对于每组测试数据:
第一行包含两个整数 nn 和 qq,表示字符串的长度以及询问的次数。
第二行包含一个长为 nn 的只包含大写英文字母的字符串 A[1,n]A[1,n]。
接下来 qq 行,每行包含两个整数 l_i,r_ili,ri,表示第 ii 次询问的参数。
保证 1 \leq T \leq 101≤T≤10,1 \leq n,q \leq 10^51≤n,q≤105,1 \leq l_i \leq r_i \leq n1≤li≤ri≤n。
对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 xx 组测试数据,接下来 qq 行,每行包含一个整数,表示字符串 A[l,r]A[l,r] 中字典序最小的子串个数,行末不要有多余空格。
1
2 3
AB
1 1
1 2
2 2
Case #1:
1
1
1 字典序最小的子串,显然长度是1,做个前缀和统计一下不同字母出现的次数就好了。然后找区间内最小的且出现次数不为零的字母就是答案。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
char s[];
LL f[][];
int main(){
int t,n,q,m,i,j,k,cas=,l,r;
scanf("%d",&t);
while(t--){
scanf("%d%d%s",&n,&q,s+);
for(i=;i<=n;++i){
for(j=;j<;++j) f[i][j]=f[i-][j];
f[i][s[i]-'A']++;
}
printf("Case #%d:\n",++cas);
while(q--){
scanf("%d%d",&l,&r);
LL ans=;
for(i=;i<;++i){
if(f[r][i]-f[l-][i]){
ans=f[r][i]-f[l-][i];
break;
}
}
printf("%I64d\n",ans);
}
}
return ;
}
序列计数
度度熊了解到,11,22,…,nn 的排列一共有 n! = n \times (n-1) \times \cdots \times 1n!=n×(n−1)×⋯×1 个。现在度度熊从所有排列中等概率随机选出一个排列 p_1p1,p_2p2,…,p_npn,你需要对 kk=11,22,33,…,nn 分别求出长度为 kk的上升子序列个数,也就是计算满足 1 \leq a_11≤a1 < a_2a2 < … < a_kak \leq n≤n 且 p_{a_1}pa1 <p_{a_2}pa2< … < p_{a_k}pak 的 kk 元组 (a_1a1,a_2a2,…,a_kak) 的个数。
由于结果可能很大,同时也是为了 ruin the legend, 你只需要输出结果对 1000000007(=10^9+7)1000000007(=109+7) 取模后的值。
第一行包含一个整数 TT,表示有 TT 组测试数据。
接下来依次描述 TT 组测试数据。对于每组测试数据:
第一行包含一个整数 nn,表示排列的长度。
第二行包含 nn 个整数 p_1p1,p_2p2, …, p_npn,表示排列的 nn 个数。
保证 1 \leq T \leq 1001≤T≤100,1 \leq n \leq 10^41≤n≤104,TT 组测试数据的 nn 之和 \leq 10^5≤105,p_1p1,p_2p2,…,p_npn 是 11,22,…,nn 的一个排列。
除了样例,你可以认为给定的排列是从所有 11,22,…,nn 的排列中等概率随机选出的。
对于每组测试数据,输出一行信息 "Case #x: c_1c1 c_2c2 ... c_ncn"(不含引号),其中 x 表示这是第 xx 组测试数据,c_ici 表示长度为 ii 的上升子序列个数对 1000000007(=10^9+7)1000000007(=109+7) 取模后的值,相邻的两个数中间用一个空格隔开,行末不要有多余空格。
2
4
1 2 3 4
4
1 3 2 4
不难想到一个O(N*N*log(N))的做法,但是这个数据一直担心会gg,写了之后也确实T了。后来经过大佬指点发现,由于数据是随机的,所以递推到某一个长度之后可能没有任何一种方案,那他之后更大的长度的方案个数也是0,就可以直接退出循环了。加一句话就过了。
f(i,j)表示以第i个数结尾的长度为j的上升序列的方案个数,转移的时候用BIT维护下,要保证当前BIT内的数值都是当前位之前的位置贡献的。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
LL mod=1e9+;
int a[],N,M;
LL C[],ans[],f[][];
inline int lowbit(int x){return x&-x;};
inline void add(int x,LL d){
while(x<=N){
C[x]+=d;
C[x]%=mod;
x+=lowbit(x);
}
}
inline LL sum(int x){
LL r=;
while(x){
r+=C[x];
r%=mod;
x-=lowbit(x);
}
return r;
}
inline void scan_d(int &ret)
{
char c;
ret = ;
while ((c = getchar()) < '' || c > '');
while (c >= '' && c <= '')
{
ret = ret * + (c - ''), c = getchar();
}
}
int main(){
int t,n,m,i,j,k,cas=;
char ch;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
N=n;
for(i=;i<=n;++i) scan_d(a[i])/*scanf("%d",a+i)*/,f[][i]=;
ans[]=n;
int cur=;
for(int len=;len<=n;++len){
ans[len]=;
if(ans[len-]==) continue;
for(i=;i<=n;++i){
LL tmp=sum(a[i]-);
ans[len]+=tmp;
add(a[i],f[cur^][i]);
f[cur][i]=tmp; }
//memset(C,0,sizeof(C));
for(i=;i<=n;++i)C[i]=;
cur^=;
}
printf("Case #%d:",++cas);
for(i=;i<=n;++i) printf(" %I64d",ans[i]%mod);
cout<<endl;
}
return ;
}
三原色图
度度熊有一张 nn 个点 mm 条边的无向图,所有点按照 1,2,\cdots,n1,2,⋯,n 标号,每条边有一个正整数权值以及一种色光三原色红、绿、蓝之一的颜色。
现在度度熊想选出恰好 kk 条边,满足只用这 kk 条边之中的红色边和绿色边就能使 nn 个点之间两两连通,或者只用这 kk 条边之中的蓝色边和绿色边就能使 nn 个点之间两两连通,这里两个点连通是指从一个点出发沿着边可以走到另一个点。
对于每个 k=1,2,\cdots,mk=1,2,⋯,m,你都需要帮度度熊计算选出恰好 kk 条满足条件的边的权值之和的最小值。
第一行包含一个正整数 TT,表示有 TT 组测试数据。
接下来依次描述 TT 组测试数据。对于每组测试数据:
第一行包含两个整数 nn 和 mm,表示图的点数和边数。
接下来 mm 行,每行包含三个整数 a,b,wa,b,w 和一个字符 cc,表示有一条连接点 aa 与点 bb 的权值为 ww、颜色为 cc 的无向边。
保证 1 \leq T \leq 1001≤T≤100,1 \leq n,m \leq 1001≤n,m≤100,1 \leq a,b \leq n1≤a,b≤n,1 \leq w \leq 10001≤w≤1000,c \in {R,G,B}c∈{R,G,B},这里 R,G,BR,G,B 分别表示红色、绿色和蓝色。
对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 xx 组测试数据,接下来 mm 行,每行包含一个整数,第 ii 行的整数表示选出恰好 ii 条满足条件的边的权值之和的最小值,如果不存在合法方案,输出 -1−1,行末不要有多余空格。
1
5 8
1 5 1 R
2 1 2 R
5 4 5 R
4 5 3 G
1 3 3 G
4 3 5 G
5 4 1 B
1 2 2 B
Case #1:
-1
-1
-1
9
10
12
17
22 跑两次kruscal就好了,一次只用条件一的边,一次用条件二的边。每次跑完之后在依次加入剩下的边更新ans,如果无法联通答案就都是-1了。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define inf 0x3f3f3f3f
int f[];
int getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
struct Edge{
int u,v,w,col,sel;
bool operator<(const Edge& C)const{
return w<C.w;
}
}e[];
int ans[],N,M;
void mst(int no){
int cnt=,cnw=;
for(int i=;i<=N;++i)f[i]=i;
for(int i=;i<=M;++i)e[i].sel=;
for(int i=;cnt<N-&&i<=M;++i){
if(e[i].col==no) continue;
int fu=getf(e[i].u),fv=getf(e[i].v);
if(fu!=fv){
e[i].sel=;
cnt++;
cnw+=e[i].w;
f[fv]=fu;
}
}
if(cnt!=N-) return;
if(ans[cnt]==-) ans[cnt]=cnw;
else ans[cnt]=min(ans[cnt],cnw);
for(int i=;i<=M;++i){
if(e[i].sel) continue;
cnt++;
cnw+=e[i].w;
if(ans[cnt]==-) ans[cnt]=cnw;
else ans[cnt]=min(ans[cnt],cnw);
}
}
int main(){
int t,n,m,i,j,k,cas=;
char ch;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
N=n,M=m;
for(i=;i<=m;++i){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
//getchar();scanf("%c",&ch);
cin>>ch;
if(ch=='R') e[i].col=;
else if(ch=='G') e[i].col=;
else if(ch=='B') e[i].col=;
}
sort(e+,e++m);
memset(ans,-,sizeof(ans));
mst();
mst(); printf("Case #%d:\n",++cas);
for(i=;i<=m;++i) printf("%d\n",ans[i]);
}
return ;
}
2018"百度之星"程序设计大赛 - 资格赛 A/B/E/F的更多相关文章
- 2018"百度之星"程序设计大赛 - 资格赛 - 题集
1001 $ 1 \leq m \leq 10 $ 像是状压的复杂度. 于是我们(用二进制)枚举留下的问题集合 然后把这个集合和问卷们的答案集合 $ & $ 一下 就可以只留下被选中的问题的答 ...
- 2018"百度之星"程序设计大赛 - 资格赛hdu6349三原色(最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6349 题目: 三原色图 Time Limit: 1500/1000 MS (Java/Others) ...
- 2018"百度之星"程序设计大赛 - 资格赛 1002 子串查询
题面又是万能的毒毒熊... 实在不想写了,就只写了这题 记26个前缀和查询枚举最小值直接算 实在是氵的死 而且我忘记输出Case #%d 想了很久 >_< #include<bits ...
- 子串查询(二维前缀数组) 2018"百度之星"程序设计大赛 - 资格赛
子串查询 Time Limit: 3500/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Subm ...
- 2018"百度之星"程序设计大赛 - 资格赛
调查问卷 Accepts: 1546 Submissions: 6596 Time Limit: 6500/6000 MS (Java/Others) Memory Limit: 262144 ...
- HDU6383 2018 “百度之星”程序设计大赛 - 初赛(B) 1004-p1m2 (二分)
原题地址 p1m2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- HDU6380 2018 “百度之星”程序设计大赛 - 初赛(B) A-degree (无环图=树)
原题地址 degree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- hdu 6082 度度熊与邪恶大魔王(2017"百度之星"程序设计大赛 - 资格赛 )
度度熊与邪恶大魔王 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- 2014年百度之星程序设计大赛 - 资格赛 第二题 Disk Schedule
双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1和北京大学OJ2677都出现了这个题目. 旅行商问题描写叙述:平面上n个点,确定一条连接各点的最短闭合旅程 ...
随机推荐
- MongoDB集群配置笔记一
MongoDB 的部署方案有单机部署.复本集(主备)部署.分片部署.复本集与分片混合部署.混合的部署方式如图: 分片集群的构造 (1)mongos :数据路由,和客户端打交道的模块.mongos本身没 ...
- HTTP 返回状态码说明
HTTP 返回状态码一.1xx - 信息提示 这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. • 100 - 继续. • 101 - 切换协议. 二.2xx ...
- 【OData】Odata能做什么?
在我看来OData就是一个实现Rest full的框架.你可以使用它对server的资源进行操作.那么它能做什么? 1. 获取资源 var context = new DefaultContainer ...
- HDU 4859 海岸线(最小割+最大独立点权变形)
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题意: 欢迎来到珠海!由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的 ...
- 【Mysql】外键
MYSQL数据表建立外键 MySQL创建关联表可以理解为是两个表之间有个外键关系,但这两个表必须满足三个条件 1.两个表必须是InnoDB数据引擎 2.使用在外键关系的域必须为索引型(Index) 3 ...
- Pandas 基础(1) - 初识及安装 yupyter
Hello, 大家好, 昨天说了我会再更新一个关于 Pandas 基础知识的教程, 这里就是啦......Pandas 被广泛应用于数据分析领域, 是一个很好的分析工具, 也是我们后面学习 machi ...
- logback的使用
一.logback与log4j的比较(摘自他人博客): 1.更快的实现 Logback的内核重写了,在一些关键执行路径上性能提升10倍以上.而且logback不仅性能提升了,初始化内存加载也 ...
- git difftool和mergetool图形化
1.当然是先安装Beyond Compare3 (此处省略安装步骤,自行百度) 2.设置difftool git config --global diff.tool bc3 git config -- ...
- C++.构造函数(超出范围)_01
环境:Win7x64.Qt5.3.2 MSVC2010 OpenGL.vs2010 1.ZC:在 构造函数 中,基类访问子类的成员 会报内存错误,如果访问的是 基本类型的话(如int) 可能还不会出错 ...
- java.io.FileNotFoundException异常,一是“拒绝访问”,二是“系统找不到指定路径”
关于java.io.FileNotFoundException异常 因为这个异常抛出俩种情况:一是“拒绝访问”,二是“系统找不到指定路径” 这里只讲明什么时候抛拒绝访问,什么时候抛找不到指定路径. 原 ...