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;
}

posted @ 2020-04-13 21:05  DinoMax  阅读(138)  评论(0)    收藏  举报