字符串

string.pas/c/cpp

1S/256MB

【题目描述】

现在给一个字符串,你要做的就是当这个字符串中存在两个挨着的字符是相同的时就将这两个字符消除。需要注意的是,当把这两个字符消除后,可能又产生一对新的挨着的字符是相同的。比如,初始的字符串是abcddc,dd是两个挨着的相同的字符,当把"dd"消除后,得到的字符串是abcc,这时cc又是两个挨着的相同的字符,所以又应该把cc消除。重复以上操作直到剩下的串中不存在两个挨着的字符是相同的为止,输出最终剩下的串。另外需要注意的是,多对相同字符的消除顺序是不会对答案产生影响的,可以证明最后他们都会达到唯一的结果,比如,对于初始字符串adccdeed,无论是adccdeed->addeed->aeed->ad还是adccdeed->adccdd->adcc->ad,最终的输出结果都是ad。

【输入】

输入文件名:string.in

输入的第一行,包含一个字符串,为初始字符串,所有的字符均为小写字母。

【输出】

输出文件名:string.out

输出为一行,包含一个字符串,为执行多次消除操作后最终剩下的字符串。

【输入样例】

adccdeed

【输出样例】

ad

【数据范围】

对于100%的数据,字符串的长度在1到200000之间。

/*
操作很麻烦,写了一个大模拟,用双向链表维护删除操作,用时1h,总觉得有超时的风险
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 200010
using namespace std;
int a[maxn],fir=,len,now;
bool vis[maxn];
struct node{
int pre,to;
}q[maxn];
char s[maxn];
bool check(){
while(vis[fir]==)fir++;
int before=;
now=fir;
for(;now<=len;now=q[now].to){
if(a[now]==a[before])return ;
before=now;
}
return ;
}
int main(){
//freopen("Cola.txt","r",stdin);
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
scanf("%s",s+);
len=strlen(s+);
for(int i=;i<=len;i++){
a[i]=s[i]-'a';
q[i].pre=i-;q[i].to=i+;
}
a[]=-;
while(){
if(check()){
while(vis[fir]==)fir++;
while(fir<=len){
printf("%c",a[fir]+'a');
fir=q[fir].to;
}
break;
}
while(vis[fir]==)fir++;
int before=;
now=fir;
int flag=,cnt=,head=fir,headto;
for(;now<=len;now=q[now].to){
if(a[now]==a[before]){
if(flag==)head=before,headto=now;
flag=;
vis[now]=;vis[before]=,cnt++;
q[q[now].to].pre=q[before].pre;
q[now].pre=q[before].pre;
q[q[before].pre].to=q[now].to;
q[before].to=q[now].to;
break;
}
before=now;
}
}
}

60分 双向链表+模拟 TLE

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define pa pair<int,int>
#define inf (1LL<<60)
#define mod 1000000007
#define ll long long
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
char a[];
int n;
int l[],r[];
void del(int x){
int L=l[x],R=r[x];
r[L]=R;l[R]=L;
}
int main(){
//freopen("string.in","r",stdin);
//freopen("string.out","w",stdout);
scanf("%s",a+);n=strlen(a+);
for(int i=;i<n;i++)r[i]=i+;
for(int i=;i<=n;i++)l[i]=i-;
for(int now=r[];now;now=r[now]){
while(now&&a[now]==a[l[now]]){
int t=r[now];
del(l[now]);del(now);
now=t;
}
}
for(int now=r[];now;now=r[now])
printf("%c",a[now]);
puts("");
return ;
}

100分 栈+链表模拟

感冒病毒

suspects.pas/c/cpp

1S/256MB

【题目描述】

一种感冒病毒正在学校里传播,这所学校有n个学生,m个学生社团,每个学生可能参加了多个社团,因为同一个社团的学生交流较多,所以如果一个学生感染上感冒病毒,那么他所在的社团里的所有学生都会感染上感冒病毒,现在已知0号学生感染上感冒病毒,问现在有多少人会感染上感冒病毒。

【输入】

输入文件:suspects.in

输入的第一行是两个整数n和m,表示学生的数目和社团的数目,学生的编号为0到n-1。

接下来m行,每行首先是一个数ki,表示这个社团有ki个人,接下来ki个整数,表示这个社团里每个学生的编号aij。

【输出】

输出文件:suspects.out

输出为一行,包含一个整数。表示感染感冒病毒的人数。

【输入样例】

100 4

2 1 10

5 10 13 11 12 14

2 0 1

2 9 2

【输出样例】

7

【数据范围】

对于100%的数据,3<=n<=30000

对于100%的数据,3<=m<=500

对于100%的数据,1<=ki<=n

对于100%的数据,0<=aij<n。

/*
一眼题,一看就是并查集,就写出来了,用时10分钟
*/
#include<iostream>
#include<cstdio>
#define maxn 30010
using namespace std;
int n,m,fa[maxn];
int find(int x){
if(fa[x]==x)return fa[x];
return fa[x]=find(fa[x]);
}
void connect(int a,int b){
int f1=find(a);
int f2=find(b);
if(f1==f2)return;
fa[f1]=f2;
}
int main(){
freopen("suspects.in","r",stdin);
freopen("suspects.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)fa[i]=i;
int x,y,z;
for(int i=;i<=m;i++){
scanf("%d",&x);
if(x>)scanf("%d",&y),y++;
if(x>){
for(int j=;j<=x;j++){
scanf("%d",&z);z++;
connect(y,z);
}
}
}
int ans=;
for(int i=;i<=n;i++)
if(find(i)==find())ans++;
printf("%d",ans);
}

100分 并查集

弱点

weakness.pas/c/cpp

2S/256MB

【题目描述】

一队勇士正在向你进攻,每名勇士都有一个战斗值ai。但是这队勇士却有一个致命弱点,如果存在i<j<k使得ai>aj>ak,则会影响他们整体的战斗力。我们将这样的一组(i,j,k)称为这队勇士的一个弱点。请求出这队勇士的弱点数目。

【输入】

输入文件:weakness.in

输入的第一行是一个整数n,表示勇士的数目。

接下来一行包括n个整数,表示每个勇士的战斗值ai。

【输出】

输入文件:weakness.out

输出为一行,包含一个整数。表示这队勇士的弱点数目。

【输入样例】

4

10 8 3 1

【输出样例】

4

【数据范围】

对于30%的数据,3<=n<=100

对于100%的数据,3<=n<=1000000

对于100%的数据,1<=ai<=1000000,每个ai均不相同

#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 1000010
int n,a[maxn],ans;
int main(){
freopen("weakness.in","r",stdin);
freopen("weakness.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
for(int k=j+;k<=n;k++){
if(a[i]>a[j]&&a[j]>a[k])ans++;
}
}
}
cout<<ans;
return ;
}

30分 暴力

/*
枚举i的话,要求左边比它大的个数和右边比它小的
*/
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 1000001
int n,tr[][maxn],a[maxn];
long long query(int x,int pos){
long long res=;
while(pos){
res+=tr[x][pos];
pos-=pos&(-pos);
}
return res;
}
void add(int x,int pos,int d){
while(pos<=maxn){
tr[x][pos]+=d;
pos+=pos&(-pos);
}
}
int main(){
freopen("weakness.in","r",stdin);
freopen("weakness.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
add(,a[i],);
}
long long ans=;
for(int i=;i<=n;i++){
add(,a[i],-);
ans+=(query(,)-query(,a[i]))*(query(,a[i]-));
add(,a[i],);
}
cout<<ans;
}

100分 树状数组

滑动的窗户

window.pas/c/cpp

3S/256MB

【题目描述】

在一个包含n个元素的数组上,有一个长度为k的窗户在从左向右滑动。窗户每滑动到一个位置,我们都可以看到k个元素在窗户中。如下的例子所示,假设数组为 [1 3 -1 -3 5 3 6 7],而k等于3:

窗户位置

最小值

最大值

[1  3  -1] -3  5  3  6  7

-1

3

1 [3  -1  -3] 5  3  6  7

-3

3

1  3 [-1  -3  5] 3  6  7

-3

5

1  3  -1 [-3  5  3] 6  7

-3

5

1  3  -1  -3 [5  3  6] 7

3

6

1  3  -1  -3  5 [3  6  7]

3

7

对于窗户滑动过的每个位置,请给出窗户内k个元素的最小值和最大值。

【输入】

输入文件:window.in

输入的第一行包括两个整数n,k,n表示数组的长度,k表示窗户的长度。

接下来一行包括n个整数,表示这个n个元素的数组。

【输出】

输出文件:window.out

输出包含两行,每行包括n-k+1个整数,第一行表示窗户从左到右滑动过程中的最小值,第二行表示窗户从左到右滑动过程中的最大值。

【输入样例】

8 3

1 3 -1 -3 5 3 6 7

【输出样例】

-1 -3 -3 -3 3 3

3 3 5 5 6 7

【数据范围】

对于100%的数据,3<=n<=1000000,1<=k<=n,数组中的每个元素均在int范围内

#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 1000010
int n,k,qmax[maxn],qmin[maxn],a[maxn],h1=,h2=,t1,t2;
int ans1[maxn],ans2[maxn];
int main(){
//freopen("Cola.txt","r",stdin);
freopen("window.in","r",stdin);
freopen("window.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<k;i++){
while(h1<=t1&&a[qmax[t1]]<=a[i])t1--;
qmax[++t1]=i;
while(h2<=t2&&a[qmin[t2]]>=a[i])t2--;
qmin[++t2]=i;
}
for(int i=k;i<=n;i++){
while(h1<=t1&&qmax[h1]<=i-k)h1++;
while(h1<=t1&&a[qmax[t1]]<=a[i])t1--;
qmax[++t1]=i;ans1[i]=a[qmax[h1]];
while(h2<=t2&&qmin[h2]<=i-k)h2++;
while(h2<=t2&&a[qmin[t2]]>=a[i])t2--;
qmin[++t2]=i;ans2[i]=a[qmin[h2]];
}
for(int i=k;i<=n;i++)printf("%d ",ans2[i]);printf("\n");
for(int i=k;i<=n;i++)printf("%d ",ans1[i]);
fclose(stdin);fclose(stdout);
return ;
}

100分 单调队列

2014-11-3 NOIP模拟赛3的更多相关文章

  1. 11/1 NOIP 模拟赛

    11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...

  2. 11.7 NOIP模拟赛

    目录 2018.11.7 NOIP模拟 A 序列sequence(two pointers) B 锁lock(思路) C 正方形square(埃氏筛) 考试代码 B C 2018.11.7 NOIP模 ...

  3. NOIP模拟赛-2018.11.7

    NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...

  4. NOIP模拟赛-2018.11.6

    NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...

  5. NOIP模拟赛-2018.11.5

    NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...

  6. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  7. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  8. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  9. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  10. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

随机推荐

  1. scanf ---------未完待续

    1.不可读入空格 #include<iostream> #include<stdio.h> using namespace std; int main() { char c[5 ...

  2. appium-环境搭建(一)

    adb命令 adb的全称为Android Debug Bridge,就是起到调试桥的作用.借助adb工具,我们可以管理设备或者手机模拟器的状态.还可以进行很多手机操作,如安装软件\系统升级\运行she ...

  3. Python基础-list,tuple,dict,set常用方法及区别

    1,列表list 列表定义方式 lis1=[1,2,3,4]#一维数组 lis2=[1,2,3,[4,5,6]]#二维数组 依次多有多维数据,套几层就是几维数组 列表的取值可以通过下标来,下标都是从0 ...

  4. Eclipse_常用技巧_01_自动添加类注释和方法注释

    一.步骤 路径A=windows-->preference-->Java-->Code Style-->Code Templates-->Comments 自动添加注释一 ...

  5. JSTL标签提示:"items" does not support runtime expressions

    今天在使用JSTL的 c:forEach 标签时,jsp提示:"items" does not support runtime expressions,后来才发现是因为taglib ...

  6. pytorch--cpu与gpu load时相互转化

    pytorch------cpu与gpu load时相互转化 torch.load(map_location=)学习 将gpu改为cpu时,遇到一个报错:RuntimeError: Attemptin ...

  7. 通过Jquery异步获取股票实时数据

    最近朋友让我帮他做个异步获取数据的程序,暂时服务器什么都没有,所以我就想先拿股票数据打个框架,方便后续开发和移植等事情 代码如下: <!-- 说明:股票看盘 作者:黑桃A 时间:2014-04- ...

  8. JS数组的sort排序

    数组sort方法排序var aa=[6,2,1,5]//默认是从小到大排序aa.sort()[1, 2, 5, 6] //下面也是从小到大排序aa.sort(function(a,b){return ...

  9. Cloudera运维

    1. 增加一个节点 1. 拷贝cm的jar包到该节点 2. 设置hostname(hostnamectl set-hostname XXX),然后修改hosts文件 3. 所有的节点添加该hostna ...

  10. bzoj 3144 切糕 —— 最小割

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3144 每个点拆成 R 个,连成一条链,边上是权值,割掉代表选这一层: 然后每个点的第 t 层 ...