Codeforces Round #632 (Div. 2)


打卡第一天


A. Little Artem

题意:给你n*m个方格,其中你可以涂上B或W,其中设如果B四周内有W这种B的个数为x,如果W四周内有B,这种W的个数为y,如果x=y+1,则成功,请你输出任意一种符合该条件的涂色方案。
思路:一开始想的是B和W交替出现,想了半天 直接一个顶角为W,其余都为B就行,这样x=2,y=1,直接出答案

#include <iostream>
using namespace std;
int main(){
	ios::sync_with_stdio(0);
	int t;
	cin>>t;
	while(t--){
		int n, m;
		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");
			 }
			 printf("\n");
		}
	}
	return 0;
}

B. Kind Anton

题意:多组输入t,之后输入一个n表示数组长度,然后输入数组a和b,但是a有一个限制条件,那就是a中的数组的值只能为0,1,-1,同时a能进行任意多次操作令a[j]=a[i]+a[j],(i<j),求是否存在操作使得数组a转变为数组b
思路:a数组中的数值很有意思,只能为0,-1,1,所以说对a[i]和b[i]进行分析可以得出一个结论
1.如果a[i]>b[i],如果对于a[i]来说,i之前不包括i,a[i]数组出现过-1,即能使得a[i]变小,即成立
2.如果a[i]<b[i],同理,如果在a[i]之前出现过1,则成立
3.如果a[i]=b[i],不须做处理
以上三个条件有一个不满足即不能使得a变为b

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <deque>
#include <cstring>
#include <algorithm>
using namespace std;
#define sc(x) scanf("%lf", &x)
const int mod = 1e9+7;
typedef long long ll;
const int M = 100010;
int a[M], b[M];
int main(){
    ios::sync_with_stdio(0);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int flag[3]={0};
        int tmp = 1;
        for(int i = 0; i < n; i++) cin>>a[i];
        for(int i = 0; i < n; i++){
            cin>>b[i];          //其实如果为了节省空间可以不用另设b数组
            if(a[i]>b[i]&&flag[2]);
            else if(a[i]==b[i]);
            else if(a[i]<b[i]&&flag[1]);
            else tmp=0;
            if(a[i]==1) flag[1] = 1;
            else if(a[i]==-1) flag[2] = 1;
        }
        if(tmp) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

C. Eugene and an array

题意:输入n表示数组长度,之后n个数为数组a的值,对a进行的操作可以为在开头或者结尾去除掉0至n个数,称为子数组,对于这个子数组来说如果其子数组没有sum=0的话就算为好数组,输出数组a有多少个好数组
思路:对前i个数求和即sum,如果sum在前面出现过则表明这i个数中有一段[j+1,i]的sum=0(j<=i),简而言之就是sum(a[1]+…+a[j])=sum(a[1]+…+a[j-1]+a[j]+…+a[i]),sum[a[j+1]+…+a[i])=0,所以选取子数组只能在这j到i里面选即为i-j-1,但问题又来了,如果这i-j中有一段是sum=0的怎么办,这里引用一个变量tmp表示距离i最近的存在sum=0的,而且这个tmp的值对于每个i来说都有用处,即便是sum[i]在前面没有出现过也是一样的道理,具体实现看代码

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define sc(x) scanf("%lf", &x)
const int mod = 1e9+7;
typedef long long ll;
const int M = 200010;
int a[M];
int main(){
    ios::sync_with_stdio(0);
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);	//存储数据
    map<ll, ll> m;
    m[0]=0;		//注意这里的m[0]=0预处理对于和为0
    ll ans = 0, sum = 0, tmp=0;		//ans表示子数组的个数,sum表示前i个的和,
    								//tmp表示距离i最近的某个区间存在sum=0的下标
    for(int i = 1; i <= n; i++){
        sum += a[i];
        if(m.count(sum)){			//如果sum在前面出现过
            tmp = max(tmp, m[sum]+1);		//max的意思就是如果这段j到i中存在sum=0的一小段取离i最近的
        }
        m[sum] = i;		//对m进行更新
        ans += i-tmp;	//加i的意思是加上这个数字子数长度分别为1到i,由这个数往前推,
        				//减去tmp的意思是前面的i是有1到tmp这段是不能加入这个子数组的
    }
    printf("%lld\n", ans);
    return 0;
}

D. Challenges in school №41

待补

F. Kate and imperfection

emmmm相对于F这题的确有点水
题意:给你一个整数n,然后从中选出K个数(这K个数是你可以决定的),之后在你选出的K个数中取其中任意两个数(注意这里是任意)求他们的gcd(a,b),即最大公因数,输出n-1个数,k的取值为2到n
思路:看到这个题目首先想到的是素数筛,因为素数之间的公因数是1,然后是逐步推,把素数筛选完之后,加入的数就肯定是合数,也可以得到一个结论加入合数后,他的次大因数必定在你选的k-1个数中。(最大因数为本身)

蒟蒻代码

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define sc(x) scanf("%lf", &x)
const int mod = 1e9+7;
typedef long long ll;
const int maxn = 500010;
int isp[maxn];
int n;
int p[maxn], len;
void init() {
    isp[0] = isp[1] = 1;
    for (int i = 2; i <= n; i++) {
        if(!isp[i]) p[++len] = i;
        for (int j = 1; j <= len && p[j]*i <= n; j++) {
            isp[i*p[j]] = p[j];			//isp中存放的是i的最小因数,如果i为质书isp的值为0
            if (i%p[j] == 0) break;
        }
    }
}
int a[maxn];
int main(){
    ios::sync_with_stdio(0);
    scanf("%d", &n);
    init();
    int j = 1;
    for(int i = 2; i <= n; i++){
        if(isp[i]!=0){
            int tmp = max(i/isp[i], isp[i]);
            a[tmp]++;	//i的次大因数,i为合数
        }else a[1]++;
    }
    for(int i = 2; i <= n; i++){
        if(a[j]) printf("%d", j),a[j]--;
        else j++, printf("%d", j), a[j]--;
        if(i!=n) printf(" ");
    }
    return 0;
}

大佬代码
看到这代码量,我哭了

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int mod = 1e9+7;
typedef long long ll;
const int maxn = 500010;
int main(){
    ios::sync_with_stdio(0);
    int n;
    cin>>n;
    vector<int> ans(n+1,1);
    for(int i = 2; i <= n; i++)
        for(int j = i+i; j <= n; j+=i)
            ans[j] = i;
    sort(ans.begin(), ans.end());
    for(int i = 2; i <= n; i++) cout<<ans[i]<<" ";
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值