A
#include<bits/stdc++.h>
using namespace std;
int box[10],maxn=0;
int main()
{
int n;
cin>>n;
while(n--)
{
string s;
cin>>s;
for(int j=0;j<7;j++)
if(s[j]=='1') box[j+1]++;
}
for(int i=1;i<=7;i++)
maxn=max(maxn,box[i]);
cout<<maxn;
}
B
#include<bits/stdc++.h>
using namespace std;
int dif[110],n,a[110],flag=1;
int main()
{
cin>>n;
if(n==2)
{
cin>>a[1]>>a[2];
cout<<a[2]+(a[2]-a[1]);
return 0;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i>=2)
{
dif[i]=a[i]-a[i-1];
if(i>=3&&dif[i]!=dif[i-1]) flag=0;
}
}
if(flag) cout<<a[n]+dif[n];
else cout<<a[n];
}
C
A. Union of Doubly Linked Lists
#include<bits/stdc++.h>
using namespace std;
int n;
struct Node
{
int l,r;
}node[110];
struct list
{
int ls,rs;
}L[110];
int main()
{
cin>>n;
int cnt=0;
for(int i=1;i<=n;i++)
scanf("%d%d",&node[i].l,&node[i].r);
for(int i=1;i<=n;i++)
{
if(node[i].l==0)//左边没有——这是一条链的左端点
{
int temp=i;
while(1)
{
if(node[temp].r==0)
break;//找到链的右端点
else temp=node[temp].r;
}
L[++cnt].ls=i;
L[cnt].rs=temp;
}
}
//cnt是链的条数,每条链的左右端点都已被储存
for(int i=1;i<cnt;i++)
{
node[L[i].rs].r=L[i+1].ls;//第i条链的右端点接第i+1条链的左端点
node[L[i+1].ls].l=L[i].rs;//第i+1条链的左端点接第i条链的右端点
}
for(int i=1;i<=n;i++)
cout<<node[i].l<<' '<<node[i].r<<endl;
}
D
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int n,a[N];
int point[N];
vector<int>vec[N];
int now=1;
int main()
{
cin>>n;
cin>>a[1];
vec[1].push_back(a[1]);
point[1]=a[1];
for(int i=2;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]<point[now])
{
vec[++now].push_back(a[i]);
point[now]=a[i];
continue;
}
int l=1,r=now;
while(l<r)
{
int mid=(l+r)/2;
if(point[mid]>a[i]) l=mid+1;
else r=mid;
}
int pos=l;
vec[pos].push_back(a[i]);
point[pos]=a[i];
}
for(int i=1;i<=now;i++)
{
for(int j=0;j<vec[i].size();j++)
printf("%d ",vec[i][j]);
printf("\n");
}
}
E
先确定一个上限,比较显然:这样排列 ((((…)))) 括号嵌套最多。这样得到的上限是 k < = n ∗ ( n − 1 ) / 2 k<=n*(n-1)/2 k<=n∗(n−1)/2
另一个问题:是否小于上限的 k 都一定有解,且如何构造。
对于 ((((…))))的括号序列,只要将里面某的一对 () 向外边提出 i 对 ()即可使得嵌套的数量减少 i。那么这样就可证明可以构造出的答案范围是连续的。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int l,r;
}b[2000];
long long ss[300000];
int main()
{
for(int i=1;i<=300000;i++)
ss[i]=ss[i-1]+(i-1);
int n;
long long k;
cin>>n>>k;
if(ss[n]<k) printf("Impossible\n");
else if(ss[n]==k)
{
for(int i=1;i<=n;i++)
printf("(");
for(int i=1;i<=n;i++)
printf(")");
}
else
{
int y=0,i;
for(i=n;i>=0;i--)
{
if(ss[i]<=k)
{
k-=ss[i];
n-=i;
break;
}
}
for(int j=1;j<=i;j++)
printf("(");
cout<<")";
for(int j=i-1;j>=1;j--)
{
if(k==j)
//补全剩下的,因为括号权值是连续的,
{
printf("()");
n--;
}
printf(")");
}
for(int j=1;j<=n;j++)
printf("()");
//因为只有一对计数为0,所以这里用于清理多余的
}
return 0;
}
递归做法
#include<bits/stdc++.h>
using namespace std;
#define ll long long
void c(ll n,ll k)
{
if(n==0)return ;
if(k>=n-1)
{
cout<<'(';
c(n-1,k-(n-1));
cout<<')';
}
else
{
cout<<"()";
c(n-1,k);
}
}
int main()
{
ll n,k;
cin>>n>>k;
if(n*(n-1)/2<k)
cout<<"Impossible";
else c(n,k);
cout<<endl;
return 0;
}
F
二分+贪心。
G
用一个优先队列来表示每个狗粮是否被吃,选择任意时刻能吃的数量的最大值即可.
#include<bits/stdc++.h>
using namespace std;
int a[200005];
priority_queue<int>q;//优先队列
int main()
{
int n,t;
cin>>n>>t;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int ans=0;
for(int i=1;i<=n;i++)
{
while(!q.empty()&&q.top()>=t-i) q.pop();
//对于每个位置,把不能吃掉的狗粮踢出去。靠后的是难凉的。
if(a[i]<t&&i<t)
q.push(a[i]-i);//如果这袋狗粮可能被吃,就放进去。
ans=max(ans,int(q.size()));//答案取最大值
}
cout<<ans;
return 0;
}