牛客暑期ACM多校 第七场
链接:https://www.nowcoder.com/acm/contest/145/C
来源:牛客网
C .题目描述
- Choose one of the operators AND (&), OR (|) or XOR (^). Suppose the current string is S = s1s2...sk. Then, for all , replace s2i-1s2i with the result obtained by applying the operator to s2i-1 and s2i. For example, if we apply XOR to {1101} we get {01}.
After n operations, the string will have length 1.
There are 3n ways to choose the n operations in total. How many of these ways will give 1 as the only character of the final string.
输入描述:
The first line of input contains a single integer n (1 ≤ n ≤ 18). The next line of input contains a single binary string s (|s| = 2
n
). All characters of s are either 0 or 1.
输出描述:
Output a single integer, the answer to the problem.
题意 : 你有 3 种操作,每次处理相邻的两个字符,问最终会有多少种操作得到 1
思路分析 : 直接一个爆搜即可,稍加一点剪枝,可以水过去
题解给的正解是,先暴力处理一下最后4种状态,即 2^16 ,下面再搜的时候复杂度会降为 3^(n - 4)
代码示例 :
using namespace std;
#define ll long long
const int maxn = 3e5+5;
const int mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f; int n, len;
char s[maxn];
int sum = 0;
int pp[30], arr[20][maxn]; void dfs(int c, int len){
if (len == 1) {
if (arr[c][1]) sum++;
return;
} for(int i = 0; i < 3; i++){
if (i == 0) {
int num = 0;
for(int j = 1; j <= len; j += 2){
arr[c+1][(j+1)/2] = arr[c][j]&arr[c][j+1];
if (arr[c+1][(j+1)/2]) num++;
}
dfs(c+1, len/2);
}
else if (i == 1){
int num = 0;
for(int j = 1; j <= len; j += 2){
arr[c+1][(j+1)/2] = arr[c][j]|arr[c][j+1];
if (arr[c+1][(j+1)/2]) num++;
}
dfs(c+1, len/2);
}
else {
int num = 0;
for(int j = 1; j <= len; j += 2){
arr[c+1][(j+1)/2] = arr[c][j]^arr[c][j+1];
if (arr[c+1][(j+1)/2]) num++;
}
dfs(c+1, len/2);
}
}
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
pp[0] = 1;
for(int i = 1; i <= 25; i++) pp[i] = pp[i-1]*2;
scanf("%d%s", &n, s+1);
len = 1;
for(int i = 1; i <= n; i++) len *= 2;
for(int i = 1; i <= len; i++) arr[1][i] = s[i]-'0'; dfs(1, len);
printf("%d\n", sum); return 0;
}
链接:https://www.nowcoder.com/acm/contest/145/E
来源:牛客网
E .题目描述
Given an undirected simple graph G, a 4-clique of G is a set of 4 nodes such that all pairs of nodes in this set are directly connected by an edge.
This task would be too easy for you, wouldn't it? Thus, your task here is to find an undirected simple graph G with exactly k 4-cliques. Can you solve this task?
输入描述:
The first line of input contains a single integer k (1 ≤ k ≤ 10
6
).
输出描述:
On the first line, output two space-separated integers, n, m (1 ≤ n ≤ 75, 1 ≤ m ≤ n * (n - 1) / 2). On the next m lines, output two space-separated integers denoting an edge of the graph u, v (1 ≤ u, v ≤ n), where u and v are the endpoints of the edge. Your graph must not contain any self-loops or multiple edges between the same pair of nodes. Any graph that has exactly k 4-cliques and satisfies the constraints will be accepted. It can be proven that a solution always exist under the given constraints.
题意 :输入一个K,代表要求你构造的图内团的大小为 4 的个数
思路分析 : 团的定义是什么:图中大小为4的点彼此之间互相连通,即大小为 4 的完全子图,我们首先可以用一些点两两之间彼此连边,此时得到的完全图是C(n, 4),但此时并不一定刚好等于 K ,因此可以最后余下几个点,用这几个点去和原先的点去连边, 假设某一个点练了X条边,则新产生的团为4 的个数为 C(X, 3),这个地方的处理可以用一个背包即可。 C(a, 3)+ C(b, 3)+ C(c, 3)+ C(d, 3)+ C(e, 3) = num
代码示例 :
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5+5; int dp[10][maxn], path[10][maxn];
int C[75][5];
int num;
int n, m, cha;
void init() {
for(int i = 3; i <= 70; i++){
int x = i*(i-1)*(i-2);
C[i][3] = x/6; int x2 = i*(i-1)*(i-2)*(i-3);
C[i][4] = x2/24;
} for(int i = 4; i <= 70; i++){
if (C[i][4] > num) break;
n = i;
}
cha = num-C[n][4]; dp[0][0] = 1;
for(int i = 1; i <= 5; i++){
dp[i][0] = 1;
for(int j = cha; j >= 0; j--){
for(int k = 3; k <= n; k++){
if (dp[i][j]) continue;
if (C[k][3] > j) break;
if (dp[i-1][j-C[k][3]]) dp[i][j] = 1, path[i][j] = k;
}
}
}
} int f[10];
bool cmp(int a, int b){
return a>b;
}
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout); cin >> num;
init(); m = n*(n-1)/2;
int an = n;
for(int i = 5; i >= 1; i--){
f[i] = path[i][cha];
cha = cha - C[f[i]][3];
m += f[i];
if (f[i]) an++;
}
sort(f+1, f+6, cmp); printf("%d %d\n", an, m);
for(int i = 1; i <= n; i++){
for(int j = i+1; j <= n; j++){
printf("%d %d\n", i, j);
}
}
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= f[i]; j++){
printf("%d %d\n", n+i, j);
}
}
return 0;
}
链接:https://www.nowcoder.com/acm/contest/145/J
J . 题目描述
A nonempty subrectangle of the grid is called sudoku-like if for any row or column in the subrectangle, all the cells in it have distinct characters.
How many sudoku-like subrectangles of the grid are there?
输入描述:
The first line of input contains two space-separated integers n, m (1 ≤ n, m ≤ 1000). The next n lines contain m characters each, denoting the characters of the grid. Each character is an English letter (which can be either uppercase or lowercase).
输出描述:
Output a single integer, the number of sudoku-like subrectangles.
说明
For simplicity, denote the j-th character on the i-th row as (i, j). For sample 1, there are 11 sudoku-like subrectangles. Denote a subrectangle
by (x
1
, y
1
, x
2
, y
2
), where (x
1
, y
1
) and (x
2
, y
2
) are the upper-left and lower-right coordinates of the subrectangle. The sudoku-like subrectangles are (1, 1, 1, 1), (1, 2, 1, 2), (1, 3, 1, 3), (2, 1, 2, 1), (2, 2, 2, 2), (2, 3, 2, 3), (1, 1, 1, 2), (1, 2, 1, 3), (2, 1, 2, 2), (1, 1, 2, 1), (1, 3, 2, 3).
说明
For sample 2, the grid has 150 nonempty subrectangles, and all of them are sudoku-like. 题意 : 一个 n*m 的矩阵,求矩阵中子矩阵的个数,要求子矩阵中每行每列都没有相同的字母,求子矩阵的个数
思路分析 :
首先预处理两个东西, le[i][j] 表示 从点 (i, j) 向左最多可以延伸的单位 ,up[i][j] 表示从点 (i, j) 最多可以向上延伸的单位
len[i] 记录的是第 i 列的最大可以向上延伸的单位
代码示例 :
ll n, m;
char s[1005][1005];
ll mp[1005][1005];
ll up[1005][1005], le[1005][1005]; void init() {
for(ll j = 1; j <= m; j++){ // 列
ll num = 0; ll len = 0;
for(ll i = 1; i <= n; i++){ // 行
if (!(num & ((1ll)<<mp[i][j]))) {
num = num|((1ll)<<mp[i][j]);
len++;
}
else {
for(ll k = i-up[i-1][j]; k <= i-1; k++){
if (mp[k][j] == mp[i][j]) break;
len--;
ll x = (1ll)<<mp[k][j];
x = ~x;
num &= x;
}
}
up[i][j] = len;
}
} for(ll i = 1; i <= n; i++){
ll num = 0, len = 0;
for(ll j = 1; j <= m; j++){
if (!(num & (1ll)<<mp[i][j])){
num = num|((1ll)<<mp[i][j]);
len++;
}
else {
for(ll k = j-le[i][j-1]; k <= j-1; k++){
if (mp[i][k] == mp[i][j]) break;
len--;
ll x = (1ll)<<mp[i][k];
x = ~x;
num &= x;
}
}
le[i][j] = len;
}
}
} ll ans = 0;
ll len[100];
void solve() {
for(int j = 1; j <= m; j++){
memset(len, 0, sizeof(len));
for(int i = 1; i <= n; i++){
for(int k = 0; k < le[i][j]; k++){
len[k] = min(len[k]+1, up[i][j-k]);
if (k) len[k] = min(len[k], len[k-1]);
ans += len[k];
}
for(int k = le[i][j]; k <= 55; k++) len[k] = 0;
}
}
printf("%lld\n", ans);
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
cin >> n >> m;
for(ll i = 1; i <= n; i++){
scanf("%s", s[i]+1);
}
for(ll i = 1; i <= n; i++){
for(ll j = 1; j <= m; j++){
if (s[i][j] >= 'a' && s[i][j] <= 'z') mp[i][j] = s[i][j]-'a';
else mp[i][j] = s[i][j]-'A'+26;
}
}
init();
solve();
return 0;
}
/*
4 4
afcd
bcda
dddd
abdc
*/
关于 le[i][j] 和 up[i][j] 两个数组,网上看到一个比较好的做法,很简便
for(int i = 1; i <= n; i++){
memset(pos, 0, sizeof(pos));
for(int j = 1; j <= m; j++){
L[i][j] = min(L[i][j-1] + 1, j - pos[s[i][j]]);
pos[s[i][j]] = j;
}
}
for(int j = 1; j <= m; j++){
memset(pos, 0, sizeof(pos));
for(int i = 1; i <= n; i++){
U[i][j] = min(U[i-1][j] + 1, i - pos[s[i][j]]);
pos[s[i][j]] = i;
}
}
le[i][j] 的值来源于两种:一种是左边的值 le[i][j-1] + 1, 另一种是与其是同一个字母的时候两者间的距离,很简洁
牛客暑期ACM多校 第七场的更多相关文章
- 2018牛客暑期ACM多校训练营第二场(有坑未填)
第二场终于等来学弟 开始(被队友带飞)的开心(被虐)多校之旅 A run A题是一个递推(dp?)+前缀和 因为看数据量比较大 就直接上前缀和了 一个比较简单的递推 没有太多难点 签到题 需要注意 ...
- 2018牛客暑期ACM多校训练营第一场(有坑未填)
(重新组队后的第一场组队赛 也是和自己队友的一次磨合吧 这场比赛真的算是一个下马威吧……队友上手一看 啊这不是莫队嘛 然后开敲 敲完提交发现t了 在改完了若干个坑点后还是依然t(真是一个悲伤的故事)然 ...
- 牛客网暑期ACM多校训练营 第九场
HPrefix Sum study from : https://blog.csdn.net/mitsuha_/article/details/81774727 k较小.分离x和k. 另外的可能:求a ...
- 牛客网暑期ACM多校训练营(第四场):A Ternary String(欧拉降幂)
链接:牛客网暑期ACM多校训练营(第四场):A Ternary String 题意:给出一段数列 s,只包含 0.1.2 三种数.每秒在每个 2 后面会插入一个 1 ,每个 1 后面会插入一个 0,之 ...
- 牛客网暑期ACM多校训练营(第五场):F - take
链接:牛客网暑期ACM多校训练营(第五场):F - take 题意: Kanade有n个盒子,第i个盒子有p [i]概率有一个d [i]大小的钻石. 起初,Kanade有一颗0号钻石.她将从第1到第n ...
- 牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?
牛客网暑期ACM多校训练营(第二场) 水博客. A.run 题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束.问一共有多少种移动的方式. 个人 ...
- 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学
牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...
- 牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献)
牛客网暑期ACM多校训练营(第三场)H Diff-prime Pairs (贡献) 链接:https://ac.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy ha ...
- 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)
2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...
随机推荐
- 2019-8-31-AutoHotKey-用打码的快捷键
title author date CreateTime categories AutoHotKey 用打码的快捷键 lindexi 2019-08-31 16:55:58 +0800 2019-06 ...
- 【u107】数字游戏(bds)
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行 ...
- 9月29更新美版T-mobile版本iPhone7代和7P有锁机卡贴解锁方法
T版是块难解的砖头,之前一直没有找到稳定解锁办法,经过多次不写努力和实验,终于解决 不管是用超雪卡贴还是GPP卡贴,第一次先用连接WIFI激活手机! 注意:一定不要用ICCID通用激活,或者是TM ...
- HTTP请求各参数详解
HTTP Request的Header信息 1.HTTP请求方式 如下表: GET 向Web服务器请求一个文件 POST 向Web服务器发送数据让Web服务器进行处理 PUT 向Web服务器发送数据并 ...
- BAT 脚本判断当前系统是 x86 还是 x64 系统
本文告诉大家在写 BAT 脚本的时候,如何判断当前的系统是 32 位系统的还是 64 位系统 通过注册表进行判断方法 @echo OFF reg Query "HKLM\Hardware\D ...
- SpringBoot使用Junit测试 防止事物自动回滚
问题:我在测试类中的save方法测试成功通过,但数据库没有插入数据 测试方法如下: @Test @Transactional // @Rollback(false) public voi ...
- jekyll 在博客添加流程图
本文告诉大家如何在博客使用流程图. 如果你使用的是我博客的模板,那么就可以直接使用我说的文件,如果是自己的主题,就需要在自己文件对应的地方加上代码. 在我的博客里,需要添加下面的js到博客,可以打开 ...
- 谈谈模型融合之一 —— 集成学习与 AdaBoost
前言 前面的文章中介绍了决策树以及其它一些算法,但是,会发现,有时候使用使用这些算法并不能达到特别好的效果.于是乎就有了集成学习(Ensemble Learning),通过构建多个学习器一起结合来完成 ...
- 基于MIG IP核的DDR3控制器(二)
上一节中,记录到了ddr控制器的整体架构,在本节中,准备把ddr控制器的各个模块完善一下. 可以看到上一节中介绍了DDR控制器的整体架构,因为这几周事情多,又要课设什么的麻烦,今天抽点时间把这个记录完 ...
- 2019 秦皇岛CCPC赛后总结
以前一直想参加ICPC或CCPC的,所以即使得知比赛会打星号,我还是想去. 感觉自己对什么都没有兴趣了,比较渴望找点快乐.. 这场比赛非常强,吉老师和杜老师都来啦,还有岛娘! 有幸要到了签名 滚榜的时 ...