牛客练习赛60 A—F题解(缺E题)
本蒟蒻这次只过了三题 赛后学习了一下出题人巨佬的标码(码风比我好多了 贴的代码有些是仿出题人)
现在将自己的理解写下来与大家分享
A
这个题一分析就是每个数字都会与所有数字&一下 (a&a=a)
&字操作是二进制同位都为一才为一 这时解法就变成统计每个二进制位上1的次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include<bits/stdc++.h> #define ll long long using namespace std; const ll maxn = 1e5; const ll maxm = 30 ; ll res; ll arr[maxn + 5 ], n, cnt[maxm + 5 ]; int main() { scanf( "%d" , &n); for ( int i = 1 ; i <= n; ++i)scanf( "%d" , &arr[i]); for ( int i = 1 ; i <= n; ++i) for ( int j = 0 ; j < 30 ; ++j) if (arr[i] & ( 1 << j))cnt[j] += 1 ; ///各位上1的个数 for ( int i = 0 ; i < 30 ; ++i)res += cnt[i] * cnt[i] * ( 1 << i); printf( "%lld\n" , res); return 0 ; } |
B
简单的n2枚举 分析一下可以知道每条边都用了n-2次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include <bits/stdc++.h> #define ll long long using namespace std; ll n,ans; ll mod= 998244353 ; struct P { ll x,y; }a[ 110 ]; ll len(P m,P n) { return abs(m.x-n.x)+abs(m.y-n.y); } int main() { scanf( "%lld" ,&n); for ( int i= 1 ;i<=n;++i)scanf( "%lld%lld" ,&a[i].x,&a[i].y); for ( int i= 1 ;i<=n;++i) { for ( int j=i+ 1 ;j<=n;++j) { ans+=(len(a[i],a[j])*(n- 2 ))%mod; } } cout<<ans%mod<<endl; return 0 ; } |
C
这是一个比较基础的dp方程的进阶 从n个物品中选k个
dp[i][j]=dp[i-1][j]+dp[i-1][j-1]
i表示到第几个字符了 j是用了几个字符
dp[i-1][j]是不用这个新加的 dp[i-1][j-1]是用这个新加的
这题的关键点是我们这样计算重复了多少字符(本质不同的解释)
其实仔细一想 我们重复计算就是相当于把 输出前面出现的那个符号在那里又多算了一次
多了哪一部分 这个重复符号上次出现的位置的dp值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#include<bits/stdc++.h> #define ll long long using namespace std; const ll maxn = 1000 ; const ll mod = 1e9 + 7 ; ll dp[maxn + 5 ][maxn + 5 ]; ll n, k, pre[maxn + 5 ]; ///pre记录上次同一个字符的出现位置 char s[maxn + 5 ]; int main() { scanf( "%d %d" , &n, &k); scanf( "%s" , s + 1 ); dp[ 0 ][ 0 ] = 1 ; ///n中选0个为1种情况 for ( int i = 1 ; i <= n; ++i) { dp[i][ 0 ] = 1 ; for ( int j = 1 ; j <= i; ++j) { dp[i][j] = dp[i - 1 ][j] + dp[i - 1 ][j - 1 ]; if (pre[s[i] - 'a' ])dp[i][j] -= dp[pre[s[i] - 'a' ] - 1 ][j - 1 ]; dp[i][j] %= mod; } pre[s[i] - 'a' ] = i; } ll res = dp[n][k]; if (res < 0 )res += mod; printf( "%lld\n" , res); return 0 ; } |
D
这题由于蒟蒻(我)追求梦想用n2枚举过了 但赛后还是写了一下正解方程(n枚举应该可以过)
写这题你需要一个 扩展欧几里得模板(能判断是否有整数解) 然后枚举一个数就把题目变成了一个模板题了 前面是n2枚举 后面大概是正解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <bits/stdc++.h> #define ll long long using namespace std; ll a,b,c,k,minl; int main() { cin>>a>>b>>c>>k; minl=min(a,min(b,c)); ll s=k/minl; for ( int i= 1 ;i<=s;++i) { for ( int j= 1 ;j<=s;++j) { ll z1=k-a*i-b*j; ll z2=k-b*i-c*j; ll z3=k-a*i-c*j; if (z1%c== 0 ){cout<<i<< " " <<j<< " " <<z1/c; return 0 ;} if (z2%a== 0 ){cout<<z2/a<< " " <<i<< " " <<j; return 0 ;} if (z3%b== 0 ){cout<<i<< " " <<z3/b<< " " <<j; return 0 ;} } } return 0 ; } #include <bits/stdc++.h> #define ll long long using namespace std; ll a,b,c,k; void exgcd(ll a,ll b,ll&x,ll&y) { if (b== 0 ) { x= 1 ; y= 0 ; return ; } exgcd(b,a%b,x,y); ll t=x; x=y; y=t-(a/b)*y; } ll gcd(ll a,ll b){ return b== 0 ?a:gcd(b,a%b); } int main() { scanf( "%lld%lld%lld%lld" ,&a,&b,&c,&k); for (ll i= 0 ;i<=k/c;i++){ ll d=k-i*c; ll x,y; exgcd(a,b,x,y); ll e=gcd(a,b); if (d%e!= 0 ) continue ; ///有无解 ll n=d/e; ll m=b/e; x*=n;y*=n; x=(x%m+m)%m; y=(d-x*a)/b; ///有无整数解 if (x>= 0 &&y>= 0 ){ printf( "%lld %lld %lld" ,x,y,i); return 0 ; } } return 0 ; } |
F
这题作为正在学习计算几何的蒟蒻(我) 那肯定是要学习的
做这题的关键是要注意画图才能理解 代码里大部分有注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#include<bits/stdc++.h> #define lowbit(x) x&(-x) #define ll long long using namespace std; typedef pair< int , int > pii; const int maxn=1e5+ 7 ; const int pi=acos(- 1.0 ); const double eps=1e- 9 ; int read() ///快读 { int x= 0 ,f= 1 ; char s=getchar(); for ( ;!isdigit(s);s== '-' && (f=- 1 ),s=getchar()); for ( ;isdigit(s);x=x* 10 +s- 48 ,s=getchar()); return x*f; } struct point { int x,y,tag; point( ) { x=y=tag= 0 ; } point( ll _x,ll _y ) { x=_x,y=_y; } bool operator==( const point& rhs ) const { return x==rhs.x && y==rhs.y; } point operator -( const point &rhs ) const { return point(x-rhs.x,y-rhs.y); } point operator+( const point &rhs ) const { return point(x+rhs.x,y+rhs.y); } ll operator * ( const point &rhs ) const { /// 叉积 return 1ll*x*rhs.y-1ll*y*rhs.x; } ll dot( const point &rhs ) const { /// 点积 return 1ll*x+rhs.x+1ll*y*rhs.y; } void get() { x=read(),y=read(); } }O,p[maxn],w1[maxn],w2[maxn],A,B; int n,m1,m2; inline bool cmpA( point a,point b ) { return (a-A)*(b-A)> 0 ; } inline bool cmpB( point a,point b ) { return (a-B)*(b-B)> 0 ; } int c[maxn]; ll ans= 0 ; void add( int x ) { while ( x<n ) c[x]++,x+=lowbit(x); } int query( int x , int tt= 0 ) { while ( x ) tt+=c[x],x-=lowbit(x); return tt;} void solve( point *t, int m ) { sort(t+ 1 ,t+ 1 +m,cmpA); ///以A点极角排序 ans+=(1ll*m*(m- 1 ))>> 1 ; ///先假设所有点对都能与线段相交 for ( int i= 1 ;i<=m;i++ ) t[i].tag=i; sort(t+ 1 ,t+m+ 1 ,cmpB); ///以B点极角排序 memset(c, 0 ,sizeof(c)); for ( int i= 1 ;i<=m;i++ ) ///减去不能与线段相交的点对 { ///这里假设线段点为P、Q 选出来的点对为 A、B 在画图过程中发现 ///选出来的能交的点对 B点要以P排序在A前面而且以Q排序也要在A前面 ///不是就减去 以树状数组解决这个区间问题 ans-=query(t[i].tag); add(t[i].tag); } } int main() { n=read(),A.get(),B.get(); for ( int i= 1 ;i<=n;i++ ) p[i].get(); for ( int i= 1 ;i<=n;i++ ) { if ( (A-p[i])*(B-p[i])>0ll ) w1[++m1]=p[i]; ///利用叉积把点分为线段上下两部分 else w2[++m2]=p[i]; } solve(w1,m1); ///第一种情况 两个点在同一侧 solve(w2,m2); ans+=1ll*m1*m2; ///第二种情况 两个点在不同侧 还是一样先假设所有点对都能与线段相交 sort(w1+ 1 ,w1+m1+ 1 ,cmpA); ///一样 以A点极角排序 sort(w2+ 1 ,w2+m2+ 1 ,cmpA); for ( int i= 1 ,bas= 1 ;i<=m1;i++ ) ///减去不能与线段相交的点对 { ///i 上侧 bas 下侧 ///画图分析 while ( bas<=m2 && (w1[i]-A)*(w2[bas]-A)> 0 ) ++bas; ///叉积判断 ans-=bas- 1 ; } sort(w1+ 1 ,w1+m1+ 1 ,cmpB); ///以B点极角排序 sort(w2+ 1 ,w2+m2+ 1 ,cmpB); for ( int i= 1 ,bas= 1 ;i<=m2;i++ ) { ///一样 while ( bas<=m1 && (w2[i]-B)*(w1[bas]-B)> 0 ) ++bas; ans-=bas- 1 ; } printf( "%lld\n" ,ans); return 0 ; } |
e题的题解可能在我大佬队友写完后贴出来(这个方向我是真不会).....
看到最后的彩蛋 推荐纯音乐 Like Sunday,Like Rain ^-^
牛客练习赛60 A—F题解(缺E题)的更多相关文章
- 牛客练习赛60 E 旗鼓相当的对手
LINK:旗鼓相当的对手 考场上遇到这种简单的树形dp优化题目我真的不一定能写出来.. 虽然这道题思路很简单 设f[i][j]表示距i距离为j的点的个数 g[i][j]表示距i距离为j的点权和. 可以 ...
- 牛客练习赛69 火柴排队 题解(dp)
题目链接 题目大意 给你一个长为n(n<=5e3)的数组a.随机使得k个元素增加d.要你求多大的概率使得,这些数组元素的相对大小不发生改变 输出 n 行每行一个整数,第 i 行的整数表示 k=i ...
- 牛客练习赛60 D 斩杀线计算大师
LINK:斩杀线计算大师 给出a,b,c三个值 求出 ax+by+cz=k的x,y,z的正整数解 保证一定有解. 考虑两个数的时候 ax+by=k 扩展欧几里得可以解决. 三个数的时候 一个暴力的想法 ...
- 牛客练习赛71 数学考试 题解(dp)
题目链接 题目大意 要你求出有多少个长度为n的排列满足m个限制条件 第i个限制条件 p[i]表示前 p[i]个数不能是1-p[i]的排列 题目思路 这个感觉是dp但是不知道怎么dp 首先就是要明白如果 ...
- 牛客练习赛66 C公因子 题解(区间gcd)
题目链接 题目大意 给你一个长为n的数组,给所有数组元素加上一个非负整数x,使得这个数组的所有元素的gcd最大 题目思路 这主要是设计到一个多个数gcd的性质 gcd(a,b,c,d.....)=gc ...
- 牛客练习赛64 D【容斥+背包】
牛客练习赛64 D.宝石装箱 Description \(n\)颗宝石装进\(n\)个箱子使得每个箱子中都有一颗宝石.第\(i\)颗宝石不能装入第\(a_i\)个箱子.求合法的装箱方案对\(99824 ...
- 牛客练习赛31 D 神器大师泰兹瑞与威穆 STL,模拟 A
牛客练习赛31 D 神器大师泰兹瑞与威穆 https://ac.nowcoder.com/acm/contest/218/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ...
- 最小生成树--牛客练习赛43-C
牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ...
- 牛客练习赛26:D-xor序列(线性基)
链接:牛客练习赛26:D-xor序列(线性基) 题意:小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y 题解:线性基 #inc ...
随机推荐
- 高阶函数---swift中的泛型介绍(一步步实现Map函数)
说明 本文内容均出自函数式 Swift一书, 此处整理仅仅是为了自己日后方便查看, 需要深入研究的话, 可以点进去购买, 支持原作者 本书由 王巍–新浪微博大神翻译 OneV's Den 喵神博客 接 ...
- Linux 环境 搭建Git 服务器,并且修改SSH端口使用
1.环境配置说明 服务器 CentOS 7 + git(git version 1.8.3.1) 客户端 Windows10 + SourceTree 2.安装 Git 服务器端安装: sudo yu ...
- Kali系统中20个超好用黑客渗透工具,你知道几个?
1. Aircrack-ng Aircrack-ng是用来破解WEP/WAP/WPA 2无线密码最佳的黑客工具之一! 它通过接收网络的数据包来工作,并通过恢复的密码进行分析.它还拥有一个控制台接口.除 ...
- 后渗透阶段之基于MSF的路由转发
目录 反弹MSF类型的Shell 添加内网路由 MSF的跳板功能是MSF框架中自带的一个路由转发功能,其实现过程就是MSF框架在已经获取的Meterpreter Shell的基础上添加一条去往“内网” ...
- 难住了同事:Java 方法调用到底是传值还是传引用
Java 方法调用中的参数是值传递还是引用传递呢?相信每个做开发的同学都碰到过传这个问题,不光是做 Java 的同学,用 C#.Python 开发的同学同样肯定遇到过这个问题,而且很有可能不止一次. ...
- Python中的BeautifulSoup库简要总结
一.基本元素 BeautifulSoup库是解析.遍历.维护“标签树”的功能库. 引用 from bs4 import BeautifulSoup import bs4 html文档-标签树-Beau ...
- 2020年,大厂常问iOS面试题汇总!
Runloop & KVO runloop app如何接收到触摸事件的 为什么只有主线程的runloop是开启的 为什么只在主线程刷新UI PerformSelector和runloop的关系 ...
- pycharm专业版激活破解(亲测有效)
完成破解步骤,亲测有效! 1.打开路径,修改hosts文件:C:\Windows\System32\drivers\etc 找到hosts文件打开 最后一行添加这行代码: 0.0.0.0 acco ...
- Python——工厂模式
目录 前言 一.简单工厂 二.工厂方法 抽象工厂 结论 参考 前言 工厂模式,顾名思义就是我们可以通过一个指定的"工厂"获得需要的"产品". 在设计模式中主要用 ...
- mysql从5.5升级到5.7遇到的坑
在安装mysql5.7时很顺利安装完成,但在启动项目时报错: [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clau ...