#include <bits/stdc++.h>
using namespace std;
/*【Row】
你有一排椅子。 如果以下两个条件成立,我们称之为“最大”的人员座位:
1.两边都没有人。2.不可能再多一个人。
座位由一个由0和1组成的字符串给出(0表示相应的座位是空的,1-占用的)。
目标是确定这次排的座位是否“最大”。第一个和最后一个座位不相邻(如果n≠2)。
n是椅子的数量。一串n个字符,每个字符都是0或1,描述座位。
如果座位是“最大”,输出“是”, 否则,打印“否”。 */
//【分析】在头尾各加一个0,出现三个连续0或者两个连续1则输出“No”。*/
int n; string ss;
int main(){
scanf("%d",&n); cin>>ss;
ss='0'+ss+'0'; //stl字符串的方便性qaq
int now0=0; bool okk=true;
for(int i=0;i<=n+1;i++){ //原串从0开始,且注意添加了字符
if(ss[i]=='1'){
if(i>0&&ss[i]==ss[i-1]){ okk=false; break; }
now0=0;
}
else{
now0++;
if(now0==3){ okk=false; break; }
}
}
if(!okk) cout<<"No"<<endl;
else cout<<"Yes"<<endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*【B. Bus of Characters】
有n排座位,每排都有2个座位。第i行中两个座位的宽度均为wi厘米。
所有的整数都是不同的。公共汽车最初是空的。每个2n站有一位乘客进入巴士。
有两种类型的乘客:
1.内向者总是选择两个座位都空的,并选择宽度最小的一排其中一个座位;
2.外向者总是选择(内向)占据一个座位的位置,选择了座位宽度最大的。
请确定每位乘客将乘坐哪一排。'0'->内向的。'1'->外向的。
保证外向者等于内向者的数量(两个数字等于n)。 */
// 分析:先给wi排序。让内向者入优先队列,外向者与顶部元素一起pop。
// 提示:使用pair数组的first & second,方便储存
typedef long long ll;
const int maxn = 200005;
pair<ll,int> a[maxn*2];
vector<pair<ll,int> >e; //用于记录w状态
int vis[maxn];
int main(){
int n; scanf("%d",&n);
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
int x; scanf("%d",&x);
pair<ll,int> p;
p.first=x; p.second=i; //存入编号
e.push_back(p);
}
sort(e.begin(),e.end()); //pair类型排序,x优先
string s; cin>>s;
priority_queue<pair<ll,int> > q; //pair类型优先队列
int cnt=0; //便于计数
for(int i=0;i<n*2;i++){ //开始上车
if(s[i]=='0'){ //内向
q.push(e[cnt]); //“排”的结构体存入q中,方便对应列寻找
cout<<e[cnt].second<<" "; //输出排数的编号
cnt++; //“排”个数增加
}
else{ //外向
cout<<q.top().second<<" "; q.pop(); //出队
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*【C. Cut 'em all!】
给一个树,问最多能删除几条边,使整个图所有相联通的部分都拥有偶数个节点。*/
/*【分析】
如果节点数是奇数,直接输出-1。首先以节点1为根节点,统计出{所有节点包含的子节点数量}。
如果该节点的儿子是奇数个,那么ans++;到了最后要记得ans-1,因为和根节点连着的边是不能去掉的。 */
const int inf = 0x3f3f3f3f;
const int maxn = 200005;
vector<int> e[maxn];
int n,k,num[maxn];
bool vis[maxn];
int dfs(int x){
vis[x]=1;
for(int i=0;i<e[x].size();i++){
if(!vis[e[x][i]]){
num[x]++; num[x]+=dfs(e[x][i]);
}//递归求出节点个数
}
return num[x];
}
int main(){
scanf("%d",&n);
for(int i=0;i<n-1;i++){ //建边
int x,y; scanf("%d%d",&x,&y);
e[x].push_back(y); e[y].push_back(x);
}
if(n%2!=0){ cout<<-1<<endl; return 0; } //n为奇数
num[1]=dfs(1); int ans=0;
for(int i=1;i<=n;i++)
if(num[i]%2) ans++; //此边要删去
cout<<ans-1<<endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*【D. Shark】
鲨鱼每天游ai公里,如果它一天游的距离大于等于k,我们就认为它游到了一个新的地方;
否则认为它这一天停留在原来的地方。这只鲨鱼到过的地方不会重复。
现在给出它n天游的距离(每天都不相等),我们要求出一个k,满足:
1.鲨鱼停留在每个地方的天数相等。(一天游的距离大于等于k时不算停留)。
2.停留过的地方尽可能多。 3.有多个解时k取最小值。 */
/* 分析》确定一个k,使得[小于k的子序列长度都是相等的],而且要尽可能多,最后k取最小值。
根据第三个限制,我们可以想到[最后的解一定是其中一个a的值加一]。
基于每个a都不相同这个条件我们可以对a先递增排序,顺序处理的时候因为是从小到大,
所以每次只需要增加一个满足条件的点即可。把这个点的标记置为1,分别判断它的左右是否标记过,
如果标记过就连成一个区间。至于怎么判断每个区间是否相等,我们可以维护一个最大区间的长度,
和所有区间的长度,我们还知道区间数量,所以有 最大长度*区间数量=总长度。
通过这个公式就可以判断是否区间长度都相等。 */
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = 1000000009;
const int maxn = 100005;
map<int, int> mp;
int a[maxn], l[maxn], r[maxn];
bool vis[maxn];
int main(){
int n; scanf("%d",&n);
for (int i=1;i<=n;++i){
scanf("%d",&a[i]);
mp[a[i]]=i;//map记录每个值原来的位置
}
sort(a+1,a+n+1);
memset(vis,0,sizeof(vis));
int len=0,ans=0,p=a[n-1]+1,cnt=0;
for(int i=1;i<=n;++i) {
int pos=mp[a[i]]; vis[pos]=1;
if(vis[pos-1]==1&&vis[pos+1]==1){ //左右都标记过,就连成一片
--cnt;
r[l[pos-1]]=r[pos+1];//更新区间范围
l[r[pos+1]]=l[pos-1];//更新区间范围
r[pos]=r[pos+1]; l[pos]=l[pos-1];
}
else if(vis[pos-1]==1){ //左边标记过
l[pos]=l[pos-1]; r[pos]=pos;
r[l[pos-1]]=pos;
}
else if(vis[pos+1]==1){ //右边标记过
r[pos]=r[pos+1]; l[pos]=pos;
l[r[pos+1]]=pos;
}
else{ //产生一个新的区间
++cnt; l[pos]=pos; r[pos]=pos;
}
int ll=r[pos]-l[pos]+1;
if(ll>len) len=ll;
if(len*cnt==i) //是否每个区间长度都相等
if(cnt>ans){
ans=cnt; p=a[i]+1;
}
}
printf("%d\n", p);
return 0;
} //来自https://blog.csdn.net/hcx11333/article/details/80387199 感谢dalao
F. The Meeting Place Cannot Be Changed