Codeforces Round #632 (Div. 2) 补题
A. Little Artem
不难发现,左上角是白色,其余是黑色就是满足题意的。。。
代码
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n,m;
read(n),read(m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1&&j==1) cout<<"W";
else cout<<"B";
}
cout<<"\n";
}
}
return 0;
}
B. Kind Anton
对于数组a中的某个数,如果想让它变大,只要它前面有1就行了,如果想让它变小,只要它前面有-1就行了。在输入时统计前i个数中1和-1的个数,最后再从后向前遍历即可。
代码
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n;
read(n);
vector<int> a(n+1),b(n+1);
vector<int> p(n+1),_p(n+1);
for(int i=1;i<=n;i++){
p[i]=p[i-1];
_p[i]=_p[i-1];
read(a[i]);
if(a[i]==1) p[i]++;
else if(a[i]==-1) _p[i]++;
}
for(int i=1;i<=n;i++) read(b[i]);
bool flag=true;
for(int i=n;i>=1;i--){
if(a[i]==b[i]) continue;
if(a[i]==1) p[i]--;
if(a[i]==-1)_p[i]--;
if(a[i]<b[i]&&!p[i]){
flag=false;
break;
}
else if(a[i]>b[i]&&!_p[i]){
flag=false;
break;
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
C. Eugene and an array
如果一个数组是不好的,那么它向左右延长得到的数组也是不好的。我们固定数组的右端r,向左找满足条件的左端的最小值l,那么应该满足l到r之间没有不好的数组。这可以通过维护数组的前缀和来实现,输入一个数后更新前缀和,并更新满足条件的l的最小值。
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
read(n);
ll sum=0,ans=0;
map<ll,int> pre;
pre[0]=1;
int l=0;
for(int i=2;i<=n+1;i++){
int v;
read(v);
sum+=v;
if(pre[sum]){
l=max(l,pre[sum]);
}
ans+=i-l-1;
pre[sum]=i;
}
cout<<ans;
}
D. Challenges in school №41
这题尤其需要注意的是,最后输出方案数应该是恰好k次。
我们可以每次从头到尾遍历字符串,找到面对面的人就将他们反转,这样得到遍历字符串的次数就是最小方案数,总的操作次数就是最大操作数。如果k不在这个范围内,输出-1.
如果不一定恰好操作k次,我们只需要把每次遍历字符串的操作输出即可,即输出最小次数。如果要求的k大于最小次数,我们只需要把一些操作拆分成若干步骤完成,总能得到k次操作的方案。
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n,k;
read(n),read(k);
string s;
cin>>s;
vector<vector<int> > res;
int sum=0;
for(;;){
res.push_back(vector<int>());
for(int i=0;i<n-1;i++){
if(s[i]=='R'&&s[i+1]=='L'){
s[i]='L';s[i+1]='R';
res.back().push_back(i+1);
i++;
}
}
sum+=res.back().size();
if(res.back().empty()){
res.pop_back();
break;
}
}
if(k<res.size()||k>sum){
cout<<"-1\n";
return 0;
}
int sz=res.size();
for(auto &ans:res){
vector<int> v;
for(int x:ans){
if(sz<k){
cout<<"1 "<<x<<"\n";
sz++;
}
else{
v.push_back(x);
}
}
if(!v.empty()){
cout<<v.size()<<" ";
for(int x:v){
cout<<x<<" ";
}
cout<<"\n";
}
else sz--;
}
return 0;
}
E. Road to 1600
首先n等于1和2的时候是无解的。只需要构造出一个n等于3的例子,可以让1在左下角。对于n大于三的情况可以看做不断对n等于三的情况进行半包围,tutorial里面那个图表述的比较明白。。。
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int a[3][3]={5,6,9,7,4,3,1,2,8};
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
read(n);
if(n<=2){
printf("-1");
return 0;
}
vector<vector<int> > ans(n,vector<int>(n));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
ans[i][j]=a[i][j]+n*n-9;
for(int i=4;i<=n;i+=2){
int k=n*n-i*i+1;
for(int j=1;j<=i;j++)
ans[j-1][i-1]=k++;
for(int j=i-1;j>=1;j--)
ans[i-1][j-1]=k++;
}
for(int i=5;i<=n;i+=2){
int k=n*n-i*i+1;
for(int j=1;j<=i;j++)
ans[i-1][j-1]=k++;
for(int j=i-1;j>=1;j--)
ans[j-1][i-1]=k++;
}
for(auto &r:ans){
for(int x:r)
printf("%d ",x);
putchar('\n');
}
return 0;
}
F. Kate and imperfection
以n等于10为例,可以构造一个数组,每次输出的答案相当于向数组增加一个元素后数组的imperfection值,最开始数组中是1。10以内有4个素数,所以最开始输出的4个结果可以看作向构造的数组中依次加入这四个素数,imperfection值当然都是1。之后向数组中加入4,这时数组的imperfection值是2,再加入6,值是3,那么是不是依次把没有加入数组的数加入进去就可以呢?并不是,因为之后加入8,得到的值是4,而加入9,得到的值是3,所以我们考虑每次加入最大因数(不包括自身)最小的数。这样的做法是正确的,也就是说每次加入一个数后,他的最大因数一定在构造的数组里。所以只要预处理每个数的最大因数,排序后依次输出就好了。
代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
read(n);
vector<int> a(n+1);
a[1]=1;
for(int i=2;i<=n;i++){
if(a[i]) continue;
a[i]=1;
for(int j=2*i;j<=n;j+=i){
if(a[j]) continue;
a[j]=j/i;
}
}
sort(a.begin()+1,a.end());
for(int i=2;i<=n;i++) printf("%d ",a[i]);
return 0;
}

浙公网安备 33010602011771号