Codeforces Round 877 (Div. 2)A-D

发布时间 2023-06-23 18:49:52作者: 橘赴亦梦人ω

Codeforces Round 877 (Div. 2)A-D

A:

有负数就输出,没有就输出最大值即可。

void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
if(a[1]<0){
cout<<a[1]<<endl;
}
else cout<<a[n]<<endl;
}

B:

调换一次两个数,使得subarray 的permutation少。 思路: 让n 在 1和2中间就可以。简单模拟。

void solve(){
int n;
cin>>n;
int x1,x2,xn;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==1) x1=i;
if(a[i]==2) x2=i;
if(a[i]==n) xn=i;
}
if((xn>x1 && xn<x2)||(xn<x1 && xn>x2)) cout<<"1 1\n";
else{
if(xn<min(x1,x2)){
cout<<xn<<" "<<min(x1,x2)<<endl;
}
else{
cout<<xn<<" "<<max(x1,x2)<<endl;
}
}
}

C:

题目: 输出一个n*m的矩阵,使得每两个相邻的数字之间的差值都不是prime。(相邻的意思是有公共边)

思路: 1不是质数。 首先想到,如果列数不是质数,比如6,就可以第一行放1 2 3 4 5 6第二行放7 8 9 10 11 12 如果m是质数,就处理不了。 可以让放的行数之间有间隙,比如原先正常第一行,第二行,第三行,第四行 可以放为:第三行,第一行,第4行,第二行。这样的话,相当于为差值多提供了一个因数。

void solve(){
int n,m;
cin>>n>>m;
vector<int>a(n+1);
int q1=n;
if(q1%2==0) q1--;
int loc=0;
while(q1>=1){
a[++loc]=q1;
q1-=2;
}
q1=n;
if(q1%2==1)q1--;
while(q1>=1){
a[++loc]=q1;
q1-=2;
}
for(int i=1;i<=n;i++){
int pos=(a[i]-1)*m;
int mm=m;
while(mm--){
cout<<(++pos)<<" ";
}
cout<<endl;
}
}

D:

给一串仅仅由大括号,小括号组成的字符串。一个人从第一个位置随便走,每次可以往右或者往左,不能出边界,问是否可以存在一种走动方式,把每次经过的括号记录下来之后是合法的序列?会有q次更改,每一次更改都是永久性的。更改一个位置从左、右括号反转一下。

思路: 首先,如果最后长度是奇数,一定找不到合法的序列。 如果在当前的串里面,存在有两个相同的符号是连续的,那么这两个连续的符号是可以一直左右左右来攻击我们需要的这个符号的数量。

额,总之我也没有想出来,是这样的: 1.只需要保证第一个连续的一定是左括号,最后一个连续的一定是右括号就可以。 2.不能出现有一种有连续的出现,但是另一种没有。 3.如果第一个和最后一个字符不是合理的,那么一定是不行的。 4.如果都没有连续的,就是可以的。

代码:

int main()
{
int n,q;
cin>>n>>q;
string s,t;
s="a";
cin>>t;
s+=t;
for(int i=1;i<=n;i++){
if(s[i]=='(') az[i]=1;
else ay[i]=1;
}
set<int>s1;
set<int>s2;
for(int i=1;i<n;i++){
if(az[i]==1 && az[i+1]==1){
s1.insert(i);
}
if(ay[i]==1 && ay[i+1]==1){
s2.insert(i);
}
}
for(int i=1;i<=q;i++){
int x; cin>>x;
if(az[x]==1) {
az[x]=0;
ay[x]=1;
if(s1.count(x)) s1.erase(x);
if(s1.count(x-1)) s1.erase(x-1);
if(ay[x-1]==1) s2.insert(x-1);
if(ay[x+1]==1) s2.insert(x);
}
else{
ay[x]=0;
az[x]=1;
if(s2.count(x)) s2.erase(x);
if(s2.count(x-1)) s2.erase(x-1);
if(az[x-1]==1) s1.insert(x-1);
if(az[x+1]==1) s1.insert(x);
}
if(ay[1]==1 || az[n]==1 || n%2==1) {
cout<<"NO\n";
continue;
}
if(s1.size()==0 && s2.size()==0){
cout<<"YES"<<endl;
continue;
}
if(s1.size()==0 && s2.size()!=0){
cout<<"NO\n";
continue;
}
if(s2.size()==0 && s1.size()!=0){
cout<<"NO\n";
continue;
}
if(*(s1.begin())<=*(s2.begin()) && *(s1.rbegin())<=*(s2.rbegin())){
cout<<"YES"<<endl;
continue;
}
cout<<"NO"<<endl;
}
return 0;
}

实现上面 借助了SET,直接枚举每一次的所有i情况就可以了。 思维题目。