【牛客OI周赛7-普及组ABCD 非官方题解】暴力,二分,KMP,尺取(STL或Hash)
A:
链接:https://ac.nowcoder.com/acm/contest/372/A
来源:牛客网
某天,一只可爱的肥橘喵在路上走,突然遇到了一个怪人,那怪人自称PM6,“小肥喵,这里有一道水题,答对了我就请你吃狗肉,答错了你就请我吃猫肉!”
喵咪瑟瑟发抖:“QAQ什么题?”
PM6道:“给你坐标轴上的N个点,求出对于每个点,有多少个点的 X 坐标和 Y 坐标都大于它。”
毫不意外,蠢肥喵完全不会这道题并面临着被做成猫肉火锅的危险,求求你救救喵咪!
输入描述:
输入包括两行,第一行是正整数n,表示点数,接下来N行每行两个数表示第i个点的横坐标和纵坐标,坐标值都是整数,输入数据中存在坐标相同的点。
对于50%的数据:0<=点的坐标大小<=10000,0<=N<=100
对于100%的数据:0<=点的坐标大小<=10000,0<=N<=1000
输出描述:
输出包括N行,第i行表示有多少个点在点i的右上方。
示例1
输入
复制
3
1 2
2 3
4 4
输出
复制
2
1
0
解题报告:
暴力没啥好说的。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
pair<int,int> p[MAX];
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) {scanf("%d%d",&p[i].first,&p[i].second);}for(int i = 1; i<=n; i++) {int ans = 0;for(int j = 1; j<=n; j++) {if(p[j].first > p[i].first && p[j].second > p[i].second) ans++;}printf("%d\n",ans);}return 0 ;
B:
题干:
链接:https://ac.nowcoder.com/acm/contest/372/B
来源:牛客网
某天,一只可爱的小兔砸在路上蹦蹦跳跳地走着,怪人PM6出现了,于是小兔子被盯上了。
PM6:“免子。哦不,小兔子。你长得真好…不对,真可爱。我这里有一道很容易很容易的题目,答对了我就请你吃萝卜,答错了你就请我吃兔肉,好不好呀~~?”
小兔砸:“萝卜!?好呀好呀好呀。”于是笨笨的兔纸入套了。
PM6:“我这里有一个由 N 个数组成的序列,给你 M 个询问,每个询问会给你一个数 X ,对于每个询问,你要回答出序列中与这个值最接近的元素。”
听完题后,兔子吓成一坨免子了,面临着变成红烧兔头的危险,求求你救救兔子!
输入描述:
第一行包含一个整数N,为序列长度。
第二行包含N个整数,为序列各元素。
第三行包含一个整数M,为PM6的询问个数。
接下来M行,每行一个整数X,为要询问最接近元素的给定值。
对于40%的数据:1<=N<=10000,1<=M<=1000
对于另外10%的数据:M=1
对于100%的数据:1 <=N<= 100000,1<=M<=10000,0<=序列中的每个数,X<=1e9
输出描述:
M行,每行有一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
示例1
输入
复制
5
2 4 5 5 7
3
2
5
6
输出
复制
2
5
5
解题报告:
二分就好了,注意特判第一个数和最后一个数,因为这两个不能用下面那个通式(因为可能pos-1==0 或者pos==n+1,此时不能放到数组中取对应数(因为都是0))(貌似很多人因为没有特判所以80分了这题。。)
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
int a[MAX];
int main()
{int n,m;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",a+i);sort(a+1,a+n+1);cin>>m;while(m--) {int x;scanf("%d",&x);int pos = lower_bound(a+1,a+n+1,x) - a;if(pos == 1) {printf("%d\n",a[1]);continue;}if(pos == n+1) {printf("%d\n",a[n]);continue;}if(abs(a[pos] - x) >= abs(a[pos-1]-x)) printf("%d\n",a[pos-1]);else printf("%d\n",a[pos]);}return 0 ;}
C:
题干:
链接:https://ac.nowcoder.com/acm/contest/372/C
来源:牛客网
另一天,一只可爱的围着围巾的肥企鹅在路上摇摇晃晃地走着,遇上了迎面走来的打着饱嗝的PM6。小企鹅预感不妙,这不就是最近有名的恶人PM6么!吓得立刻扭头就想跑。
PM6:“小火汁,站住!我不吃你(谁叫你是保护动物)。我这有一道简单题,如果你答对了,我就给你吃鱼肉,如果你答错了,就免费帮我充游戏币!”
企鹅:“_(:3J∠)_(默默摘掉围巾)”
PM6:“我给你一个文本串 S ,再给你两个串A、B,你要将文本串中的 A 都转换成 B ,转换后的字符不再参与转换,输出最终的文本串。”
求求你救救企鹅!
输入描述:
第一行输入一个文本串 S 。
第二行输入字符串 A 。
第三行输入字符串 B 。
|S|为S的长度,|A|为A的长度,|B|为B的长度,所有字符都是小写字母,保证 |A| <= |S| 。
对于50%的数据:1<= |A|、|B|、|S| <=1000
对于100%的数据:1<= |A|、|B|、|S| <=1000000
输出描述:
只有一行,输出转换后的文本串。
示例1
输入
复制
abababcd
ab
cd
输出
复制
cdcdcdcd
解题报告:
KMP就好了,记录下来每一个匹配的第一个位置,然后遍历整个字符串,遇到匹配的位置的时候就输出替换串,直到遍历完第一个字符串。
AC代码:
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
char s[1000005];
char t[1000005];
char ac[1000005];
int Next[1000005];
int ans[1000005];
int len1,len2,cnt;
void getnext() {int j = 0,k = -1;Next[0] = -1;while(j<len2-1) {if(k == -1 || t[j] == t[k]) {j++,k++;Next[j] = k;} else k = Next[k];}
}
int kmp() {int i=0,j=0;while(i < len1) {if(j == -1 || s[i] == t[j]) {i++,j++;} else {j=Next[j];}if(j >= len2) {ans[++cnt] = i-len2;j=0;}}return cnt;}
int main() {scanf("%s",s);scanf("%s",t);scanf("%s",ac);len1 = strlen(s);len2 = strlen(t);getnext();kmp();//printf("%d\n",kmp());int cur = 1;int i = 0;//cout << "ans**" << ans[1]<<endl;while(1) {if(i >= len1) break;if(cur <= cnt) {while(i < ans[cur]) {printf("%c",s[i]);i++;}cur++;i += len2;printf("%s",ac);}else {printf("%c",s[i]),i++;} }return 0;
}
题干:
链接:https://ac.nowcoder.com/acm/contest/372/D
来源:牛客网
可能很多人要吐槽为什么标题不是“救救blabla”了。
怪人PM6喜欢数糖纸,不同的糖纸有不同的颜色,一共有 N 张糖纸,第 i 张糖纸颜色为 Ci ,它们的位置都是固定的。PM6喜欢五彩缤纷的糖纸,所以他不希望有重复的颜色。他有一次机会,可以收集任意一段连续区间内的糖纸。求出PM6最多能收集多少张糖纸。
输入描述:
第一行一个正整数 N ,表示共有 N 张糖纸。
第二行共有 N 个正整数,第 i 个正整数表示第 i 张糖纸的颜色 Ci
对于20%的数据:1<=N<=100
对于40%的数据:1<=N<=1000
对于100%的数据:1<=N<=1e6,0<=Ci<=1e9
输出描述:
一个整数表示PM6最多能收集多少张糖纸。
示例1
输入
复制
5
1 2 2 3 4
输出
复制
3
说明
PM6可以收集第3到第5张的糖纸,共有三张。
解题报告:
尺取法。
AC代码:(每次固定右边界,来移动左边界)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxn 1000000
int a[maxn+5];
bool b[1000000005];
int main()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);int l=0,ans=1;for(int i=1;i<=n;i++){while(b[a[i]])b[a[++l]]=false;b[a[i]]=true;ans=max(ans,i-l);}printf("%d\n",ans);return 0;
}
AC代码2:(固定左边界看可以到达的右边界)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
const int FFF = 5e7 + 6;
int mp[MAX];
int cnt,a[MAX];
bool vis[FFF];
int HH(int x) {return (1LL*13531*x)%(FFF-100);
}
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",&a[i]),mp[i] = HH(a[i]);int l = 1,r = 1,ans = 0;while(l<=r && l <= n) {while(vis[mp[r]] == 0 && r <= n) {vis[mp[r]] = 1,r++;}ans = max(ans,r-l);vis[mp[l]] = 0;l++;}printf("%d\n",ans);return 0 ;}
这个实现方法很多,可以Hash可以直接开1e9的数组可以unordered_map,可以用二分来离散化(但是离散化完了要重新记录到一个数组中,这样使用的时候是O1的,不能每次使用都从重新计算,因为常数有点扛不住、、)
并且Hash的时候注意不能用rand(),不然可能本来相同的值可能就会被映射到不同地方去了。
这样写显然错误:(越界了)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e6 + 5;
const int FFF = 5e7 + 6;
int mp[MAX];
int cnt,a[MAX];
bool vis[FFF];
int HH(int x) {return (1LL*13531*x)%(FFF-1);
}
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",&a[i]),mp[a[i]] = HH(a[i]);int l = 1,r = 1,ans = 0;while(l<=r && l <= n) {while(vis[mp[a[r]]] == 0 && r <= n) {vis[mp[a[r]]] = 1,r++;}ans = max(ans,r-l);vis[mp[a[l]]] = 0;l++;}printf("%d\n",ans);return 0 ;}
常数很小的unordered_map(400ms)(我写的就800ms、、)
#include<cstdio>
#include<unordered_map>
using namespace std;int main()
{unordered_map<int,int>pos;int n,x,now=0,ans=1;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&x);now=i-pos[x]>now?now+1:i-pos[x];ans=ans>now?ans:now;pos[x]=i;}printf("%d\n",ans);return 0;
}
还可以直接取模:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
#define N 1000001
#define P 1651469
int n,a[N],ans=0;
bool v[N*2];
int main() {cin>>n;for(int i=1;i<=n;i++) scanf("%d",&a[i]);int l=1,r=1;v[a[1]%P]=1;while(r<n) {if(v[a[r+1]%P]) {while(a[r+1]!=a[l])v[a[l++]%P]=0;l++;}v[a[++r]%P]=1;ans=max(ans,r-l+1);}cout<<ans<<endl;
}
写在后面:
纪念第一场ak...虽然题目很水但毕竟是不熟悉的OI赛制。继续加油!
【牛客OI周赛7-普及组ABCD 非官方题解】暴力,二分,KMP,尺取(STL或Hash)相关推荐
- 牛客OI周赛2-提高组
A.游戏 链接:https://www.nowcoder.com/acm/contest/210/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他 ...
- 【牛客 - 371牛客OI周赛7-提高组B】小睿睿的询问(RMQ,ST表维护下标)
题干: 链接:https://ac.nowcoder.com/acm/contest/371/B 来源:牛客网 小睿睿的n个妹纸排成一排,每个妹纸有一个颜值val[i].有m个询问,对于每一个询问,小 ...
- 【牛客 - 371牛客OI周赛7-提高组A】小睿睿的等式(dp,暴力 )
题干: 链接:https://ac.nowcoder.com/acm/contest/371/A 来源:牛客网 小睿睿在游戏开始时有n根火柴棒,他想知道能摆成形如"A+B=n"的等 ...
- 牛客OI周赛7-提高组 A 小睿睿的等式
链接:https://ac.nowcoder.com/acm/contest/371/A 来源:牛客网 小睿睿在游戏开始时有n根火柴棒,他想知道能摆成形如"A+B=n"的等式且使用 ...
- 牛客OI周赛7-提高组 B小睿睿的询问(ST打表)
链接:https://ac.nowcoder.com/acm/contest/371/B 来源:牛客网 小睿睿的n个妹纸排成一排,每个妹纸有一个颜值val[i].有m个询问,对于每一个询问,小睿睿想知 ...
- 牛客OI周赛15-普及组
1. 咪咪游戏 bool f1,f2,f; f1用于记录m f2用于记录q f用于判断串的好坏.1为坏,0为好 注意几种情况: mqm mmq 具体看代码: #include<bits/stdc ...
- 牛客OI周赛10-提高组:B-Taeyeon的困惑(值域线段树)
做法 单点加单点删,在值域线段树上直接二分就能求值前\(K\)小的和 Code #include<bits/stdc++.h> typedef long long LL; const LL ...
- 牛客OI周赛6-提高组 B 践踏
践踏 思路: 如果k不为0, 那么就是对k取模意义下的区间更新, 单点查询 否则, 就是普通的区间更新, 单点查询 代码: #pragma GCC optimize(2) #pragma GCC op ...
- 牛客OI周赛4-提高组 C 战争(war)
战争(war) 思路: 二分答案, 找到第一个不满足条件的位置 首先对于一个值来说, 所有这个值的区间肯定有交区间, 然后在这个交区间内不能出现比它小的数 所以我们check时从大的值开始考虑, 求出 ...
最新文章
- 三万字,Spark学习笔记
- 软件工程--软件危机-生命周期-软件过程
- python学习笔记--Django入门二 Django 的模板系统
- 打包或者编译python程序
- Windows隐藏工具栏并使程序窗口全屏显示
- omnet++中基础案例tictoc1内容解析
- 瑜欣平瑞通过注册:年营收6.6亿 胡云平一家三口为实控人
- Benchmarking Learned Indexes(VLDB2021)
- 渐变插画:使用PSPS绘制渐变风格插画
- 2022-2028年中国物流地产行业市场发展潜力及投资风险预测报告
- git如何忽略文件或者文件夹
- 四种最令人讨厌的编程语言
- 耶鲁大学教授:研究生做科研的 11 条 “军规“
- Ackerman数学函数
- NOI:2722 和数
- mysql中报了 tmp空间不足的问题,【案例】Oracle安装 检测阶段警告Free space: /tmp空间不足解决办法...
- ubuntu-系统密匙
- opengl 入门学习
- php zlib 压缩图片,整站开启php zlib(gzip)压缩输出功能的方法
- C++程序 :“21 点“纸牌游戏
热门文章
- 【转贴】利用 Javascript 获取 URL 参数(适合IE、FF)
- NOD32升级ID获取器For流星无语更新了
- 第二课 决策树与随机森林
- [密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]42蒙哥马利乘法,哪里泄漏侧信道路吗?
- [hackinglab][CTF][脚本关][2020] hackinglab 脚本关 writeup
- [剑指offer]面试题第[60]题[JAVA][n个骰子的点数][动态规划][空间优化]
- [剑指offer]面试题第[54]题[JAVA][二叉搜索树的第k大节点][递归][迭代]
- [区块链与密码学][王小云院士][部分PPT][20200507]
- ubantu 添加防火墙策略_Ubuntu 14.04 配置iptables防火墙
- java 不执行构造函数_函数作为构造函数执行,但不作为函数执行