Codeforces Round #632 Div. 2
比赛链接 https://codeforces.com/contest/1333
比赛记录 https://blog.csdn.net/cheng__yu_/article/details/105395197
A. Little Artem(水)
题意:用W和B给矩阵涂色,要求黑白相邻的点:B=W+1
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int t;
int n,m;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
if(i==1&&j==1)
printf("W");
else
printf("B");
puts("");
}
}
return 0;
}
B. Kind Anton
题意:a数组由{-1,0,1}组成。可以对a数组做无限次
a
j
=
a
i
+
a
j
a_j=a_i+a_j
aj=ai+aj 的操作,问最后能否变成 b 数组
思路:
- b [ i ] > a [ i ] b[i]>a[i] b[i]>a[i],只要 i 的前面有 1 1 1 就可以
- b [ i ] < a [ i ] b[i]<a[i] b[i]<a[i],只要 i 的前面有 − 1 -1 −1 就可以
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
int t,n;
bool v1[maxn],v2[maxn];
int a[maxn],b[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
memset(v1,false,sizeof(v1));
memset(v2,false,sizeof(v2));
scanf("%d",&n);
bool flag1=false,flag2=false;
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
if(flag1) v1[i]=true;
if(flag2) v2[i]=true;
if(a[i]==1) flag1=true;
if(a[i]==-1)flag2=true;
}
for(int i=1;i<=n;++i)
scanf("%d",&b[i]);
if(b[1]!=a[1])
{
puts("NO");
continue;
}
bool valid=true;
for(int i=n;i>=2;--i)
{
if(b[i]==a[i])
continue;
if(b[i]>a[i])
{
if(!v1[i])
{
valid=false;
break;
}
}
if(b[i]<a[i])
{
if(!v2[i])
{
valid=false;
break;
}
}
}
if(valid)
puts("YES");
else
puts("NO");
}
return 0;
}
C. Eugene and an array(前缀和零集)
题意:一个数组没有 0 集(某一段连续相加为0)则认为是好数组。给定一个数组求子数组是好数组的数量
思路:每一个点往左找能够到达的最远的点,即不超过 0 集
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int n,x;
map<ll,int> m;
int main()
{
scanf("%d",&n);
ll pref=0,ans=0;
int l=0;
m[0]=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&x);
pref+=x;
if(m.count(pref))
l=max(l,m[pref]+1);
ans+=i-l;
m[pref]=i;
}
printf("%lld\n",ans);
return 0;
}
D. Challenges in school №41(模拟)
思路:预处理同时转向,然后拆成 k 次输出
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int n,k;
string s;
vector<int> vec[maxn];
int main()
{
cin>>n>>k>>s;
s="0"+s;
int cnt=0;
int sum=0;
while(1)
{
bool ok=false;
cnt++;
for(int i=1;i<n;++i)
{
if(s[i]=='R'&&s[i+1]=='L')
{
vec[cnt].push_back(i);
swap(s[i],s[i+1]);
i++;
ok=true;
}
}
if(!ok)
break;
sum+=vec[cnt].size();
}
cnt--;
if(k<cnt||k>sum)
{
puts("-1");
return 0;
}
for(int i=1;i<=cnt;++i)
{
while(!vec[i].empty()&&k>cnt-i+1)
{
puts("1");
cout<<vec[i].back()<<"\n";
vec[i].pop_back();
k--;
}
if(!vec[i].empty())
{
cout<<vec[i].size()<<" ";
for(auto j : vec[i])
cout<<j<<" ";
puts("");
k--;
}
}
return 0;
}
E. Road to 1600(构造)
题意:构造一个
n
×
n
n \times n
n×n 的矩阵,使得骑士的花费比皇后的少
思路:构造一个
3
×
3
3 \times 3
3×3 的矩阵,利用皇后的性质,让它斜着走到某个角落,从而多出花费
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=500+10;
int n;
int a[maxn][maxn];
int main()
{
cin>>n;
if(n==1||n==2)
{
puts("-1");
return 0;
}
int cnt=0;
for(int i=n;i>=4;--i)
{
if(i&1)
{
for(int j=1;j<=i;++j)
a[j][i]=++cnt;
for(int j=i-1;j>=1;--j)
a[i][j]=++cnt;
}
else
{
for(int j=1;j<=i;++j)
a[i][j]=++cnt;
for(int j=i-1;j>=1;--j)
a[j][i]=++cnt;
}
}
int x=n*n-9;
a[1][1]=4,a[1][2]=3,a[1][3]=1;
a[2][1]=5,a[2][2]=2,a[2][3]=8;
a[3][1]=9,a[3][2]=6,a[3][3]=7;
for(int i=1;i<=3;++i)
for(int j=1;j<=3;++j)
a[i][j]+=x;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
printf("%d%c",a[i][j],j==n?'\n':' ');
return 0;
}
F. Kate and imperfection(思维)
题意:给定集合S:
{
1
,
2
,
…
,
n
}
\{1,2,\dots ,n \}
{1,2,…,n}找所有 k 子集中,最大gcd(a,b)最小的子集,定义这个最大gcd(a,b)为
I
i
I_i
Ii,输出
I
2
I_2
I2 到
I
n
I_n
In
思路:假设构造一个 这样的子集,那就是先把 1和质数都丢到集合里面去,然后是2的倍数,3的倍数,4的倍数,5的倍数。如果 x 的 gcd 最后被 a 更新,x 加入集合后的gcd就是 a
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int n;
int main()
{
scanf("%d",&n);
vector<int> ans(n + 1, 1);
for(int i=2;i<=n;++i)
for(int j=2*i;j<=n;j+=i)
ans[j]=i;
sort(ans.begin(), ans.end());
for(int i=2;i<=n;++i)
printf("%d%c",ans[i],i==n?'\n':' ');
return 0;
}