考场上只做出了ABDE

C都挂了。。。

题解:

A

题解:

模拟

判断前面一段是否相同,后面一段是否相同,长度是否够(不能有重叠)

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,m;
string a,b; int main(){
n=read(),m=read();
cin>>a>>b;
int pos=-;
for(int i=;i<n;i++){
if(a[i]=='*'){
pos=i;
break;
}
}
if(pos==-){
if(a==b) puts("YES");
else puts("NO");
return ;
} if(n>m+){
puts("NO");
return ;
} for(int i=;i<pos;i++){
if(a[i]!=b[i]){
puts("NO");
return ;
}
}
for(int i=n-;i>pos;i--){
if(a[i]!=b[i-n+m]){
puts("NO");
return ;
}
}
puts("YES");
return ;
}

B

题解:

简单计算

考虑几种情况:

1. k<=n+1 那么任意一种构造都可行 答案为(k-1)/2

2. k>n+n-1 没有可行解 答案为零

3. 从(k-n)+n到(k/2+k/2) 分k的奇偶性讨论一下

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} ll n,k; int main(){
n=read();k=read();
ll ans=;
if(k<=n+) ans=(k-)/;
else if(k>n+n-) ans=;
else{
ll nw=k/;
ll l=k-n;
if(k%==) nw--;
ans=nw-l+;
}
cout<<ans<<endl;
return ;
}

C

题解:

模拟

看到(就加进去 直到够了为止

但是如果用string s; s+='(';

由于string特别慢 于是会超时。。。

所以我们改用数组存储每一位是(还是)

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,m;
string s;
string ans;
int res[],sz; int main(){
n=read(),m=read();
cin>>s;
int num=m/;
int nw=,dif=;
for(int i=;i<s.size();i++){
if(s[i]=='('){
nw++;dif++;
res[++sz]=;
if(nw==num) break;
}
else{
if(dif){
res[++sz]=;
dif--;
}
}
}
while(dif--) res[++sz]=;
for(int i=;i<=sz;i++)
if(res[i]==) putchar('('); else putchar(')');
puts("");
return ;
}

D

题解:

首先我们把整个刷上1

然后0的情况就没有了

剩下我们按照题意模拟

每个数我们找到最左的位置和最右的位置

在线段树上更新 把这段区间刷成这个数

注意如果最大的数没有出现 那么我们得加上这个数 因为他是最后刷的 所以可以放在任何为0的位置上

然后如果现在的这个序列和原来的有矛盾(原来某一位和现在不同) 那么就是-1

否则输出这个序列

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} const int maxn=;
int n,q;
int a[maxn];
int l[maxn],r[maxn]; struct Node{
int l,r,val;
int tag;
} tr[maxn*]; #define lc (i<<1)
#define rc (i<<1|1) void build(int i,int l,int r){
tr[i].l=l,tr[i].r=r;
if(l==r)
return;
int md=(l+r)>>;
build(lc,l,md);
build(rc,md+,r);
} void pushdown(int i){
if(!tr[i].tag) return;
tr[lc].tag=tr[rc].tag=tr[lc].val=tr[rc].val=tr[i].tag;
tr[i].tag=;
return;
} void upd(int i,int l,int r,int v){
if(tr[i].l>=l && tr[i].r<=r){
tr[i].val=v;
tr[i].tag=v;
return;
}
if(tr[i].l>r || tr[i].r<l) return;
pushdown(i);
upd(lc,l,r,v);upd(rc,l,r,v);
} int ask(int i,int pos){
if(tr[i].l>pos || tr[i].r<pos) return ;
if(tr[i].l==tr[i].r) return tr[i].val;
pushdown(i);
return max(ask(lc,pos),ask(rc,pos));
} int main(){
n=read(),q=read();
bool ok=;
int mx=;
rep(i,,n){
a[i]=read();
if(a[i]==) ok=;
mx=max(mx,a[i]);
}
if(!ok){
if(mx!=q){
puts("NO");
return ;
}
} if(mx!=q){
rep(i,,n){
if(a[i]==){
a[i]=q;
break;
}
}
} rep(i,,n){
int nw=a[i];
if(l[nw]==) l[nw]=i;
r[nw]=max(r[nw],i);
} build(,,n);
l[]=,r[]=n;
rep(i,,q)
if(l[i]) upd(,l[i],r[i],i); rep(i,,n){
int nw=ask(,i);
if(a[i] && a[i]!=nw){
puts("NO");
return ;
}
a[i]=nw;
} puts("YES");
rep(i,,n)
printf("%d ",a[i]);
puts(""); return ;
}

E

题解:

交互题

很有趣

首先我们可以方便的得出前n-1步

就是每次询问当前格子向右的一个格子能不能到(n,n)

如果能 那么向右走 否则向下走

这样我们可以走到对角线上

然后不能这么询问了

所以我们反过来做

但是因为路径不止一条 我们有可能不能走到同一个对角线上的格子

怎么办呢

我们换一种询问方式

从(n,n)开始

然后每次询问当前格子的上方一个格子能否到达之前哪条路径上与之距离为n-1的那个格子

具体见代码

如果能走 就往上走 否则往左走

为什么是对的呢

因为我们一定会得到所有路径里最靠右的那一条路径

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n;
string ans1,ans2; bool ask(int a,int b,int c,int d){
printf("? %d %d %d %d\n",a,b,c,d);
fflush(stdout);
string ret;
cin>>ret;
if(ret=="YES") return ;
else return ;
} int main(){
n=read();
int nwx=,nwy=;
for(int i=;i<n;i++){
bool nw=ask(nwx,nwy+,n,n);
if(nw) ans1=ans1+'R',nwy++;
else ans1=ans1+'D',nwx++;
}
int xx=n,yy=n;
for(int i=n-;i>=;i--){
if(ans1[i]=='R') nwy--;
else nwx--;
bool nw=ask(nwx,nwy,xx-,yy);
if(nw) ans2='D'+ans2,xx--;
else ans2='R'+ans2,yy--;
}
cout<<"! "<<ans1<<ans2<<endl;
fflush(stdout);
return ;
}

F

题解:

好题

首先我们先把那些“我的路径”加进图中

用并查集维护连通性

然后对于每一条新的路径:

如果两端在一个联通块内 那么记录下来

否则加进图中 并且更新并查集

这样我们得到一棵树和一些边

然后dfs一遍整理树的结构 求出每个点的father和depth

下面是精华部分

我们还是用一个并查集维护这棵树

现在我们要做的操作是:对于之前每条未加进图中的边,我们把两端点之间的路径更新成这条边的边权,不能重复更新

因为输入的时候就是排好序的所以不需要重复更新

问题在于每条边如何正好被更新一次

就是说我们在更新后边的时候要跳过一些前边被更新过的边

我们用fa[x]表示这个点在往上跳的时候跳到的点 也就是说从x到fa[x]的路径都被更新过 并且fa[x]到f[fa[x]]这条边没有被更新

那么直接这样跳一跳直到两个端点跳到同一个点就结束了

怎么维护fa呢

我们只需要在往上跳的时候令fa[x]=fp(f[x])就可以了 fp在这里表示的就是找到上一个没有更新的点

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} const int maxn=; int n,m,k,num;
int fa[maxn]; struct Edge{
int fr,to,len,tp;
};
vector<Edge> edges;
vector<int> gr[maxn]; inline int fp(int x){if(fa[x]==x) return x;return fa[x]=fp(fa[x]);}
inline void uni(int a,int b){a=fp(a),b=fp(b);if(a!=b) fa[a]=b;} void add_edge(int a,int b,int l,int t){
edges.pb((Edge){a,b,l,t});
edges.pb((Edge){b,a,l,t});
num=edges.size();
gr[a].pb(num-);
gr[b].pb(num-);
} int A[maxn],B[maxn],L[maxn],cnt;
int f[maxn],d[maxn],res[maxn]; void dfs(int x,int pa=){
f[x]=pa;
for(int i=;i<gr[x].size();i++){
int ind=gr[x][i];
Edge nw=edges[ind];
if(nw.to==f[x]) continue;
d[nw.to]=d[x]+;
dfs(nw.to,x);
}
} int ans[maxn]; int main(){
// freopen("in","r",stdin);
n=read(),k=read(),m=read();
rep(i,,n) fa[i]=i;
for(int i=;i<=k;i++){
int a=read(),b=read();
add_edge(a,b,,);
uni(a,b);
}
for(int i=;i<=m;i++){
int x=read(),y=read(),l=read();
int fx=fp(x),fy=fp(y);
if(fx!=fy){fa[fx]=fy;add_edge(x,y,l,);}
else{A[++cnt]=x,B[cnt]=y,L[cnt]=l;}
} d[]=;
dfs(); for(int i=;i<=n;i++)
fa[i]=i; for(int i=;i<=cnt;i++){
int nwx=A[i],nwy=B[i],nwl=L[i];
nwx=fp(nwx),nwy=fp(nwy);
while(nwx!=nwy){
if(d[nwx]>=d[nwy]){
res[nwx]=nwl;
fa[nwx]=fp(f[nwx]);
nwx=fa[nwx];
}
else{
res[nwy]=nwl;
fa[nwy]=fp(f[nwy]);
nwy=fa[nwy];
}
}
} //for(int i=1;i<=n;i++) cout<<res[i]<<endl; ll ans=;
for(int i=;i<=n;i++){
for(int j=;j<gr[i].size();j++){
int ind=gr[i][j];
Edge nw=edges[ind];
if(nw.to==f[i] && nw.tp==){
if(fa[i]==i){
puts("-1");
return ;
}
ans+=res[i];
}
}
}
cout<<ans<<endl;
return ;
}

总结

1. 字符串string类很慢 尽量不要用string加string的操作

2. 想好了再写 不要出现细节错误

最新文章

  1. highchart导出功能的介绍更改exporting源码
  2. Celery 框架学习笔记
  3. CentOS6.5 (64bit) 光盘内部FTP源
  4. c++ STL中的vector与list为什么没有提供find操作?
  5. [3].jekyll的基础
  6. 整除的尾数[HDU2099]
  7. bfs A strange lift
  8. 通过批处理(bat)命令创建mysql数据库及用户等
  9. android 上下文菜单详解
  10. The required Server component failed to start so Tomcat is unable to start解决之一
  11. [转载]Sublime Text 2 - 性感无比的代码编辑器!程序员必备神器!跨平台支持Win/Mac/Linux
  12. requirejs实践一 加载JavaScript文件
  13. yii操作数据库(PDO)
  14. Hibernate在自由状态和持久的状态转变
  15. 关于 &lt;textarea &gt;&lt;/textarea &gt;标签在苹果微信浏览器出现 内阴影
  16. ELK快速搭建日志平台
  17. poj3984迷宫问题(DFS广搜)
  18. mac下进行连接pptp协议
  19. 浅谈前端三大框架Angular、react、vue
  20. 01-Python的基础知识3

热门文章

  1. 文本分析实例---QQ聊天记录分析
  2. mips-openwrt-linux-gcc test_usbsw.c -o usbsw 编译问题
  3. 理解和使用WPF 验证机制
  4. 应用require.js进行javascript模块化编程小试一例
  5. bind_ip
  6. spark 33G表
  7. C++中的const完全解析
  8. 【POJ 1159】Palindrome
  9. MFC上显示摄像头JPEG图片数据的两种方法
  10. spring cloud 服务消费