七夕没女朋友呜呜呜T_T (2021牛客七夕节场)

52 篇文章 1 订阅
34 篇文章 0 订阅

8.19一点凌晨睡不着 就想着来做点事 思来想去不如来写题算了 杭电多校和牛客竞赛的题还没补 来一边写一边补七夕场的题

A题是一个二次元喂狗粮的问题就不写了┭┮﹏┭┮
C题是一个开玩笑的题hh
E是一个推理的也不写了0.0

D-亲密数:
这道题有个收获的地方就是求因子和:

LL find(LL x)
{
    int sum = 1, t = sqrt(x);
    for (int i = 2; i <= t; ++i)
        if (x % i == 0) 
            sum += i + x / i;
    if (t * t == x) 
        sum -= t;
    return sum;
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long

LL find(LL x)
{
    int sum = 1, t = sqrt(x);
    for (int i = 2; i <= t; ++i)
        if (x % i == 0) 
            sum += i + x / i;
    if (t * t == x) 
        sum -= t;
    return sum;
}

int main(){
	LL l,r;
	cin>>l>>r;
	for(LL i=l;i<=r;i++){
		LL x=find(i);
		LL y=find(x);
		if(i==y && y<x && x<=r){
			cout<<y<<" "<<x<<endl;
			return 0;
		}	
	}
	cout<<"-1"<<endl;
	return 0;
} 

G-ORMAX:
思路:容易知道|运算的结果是单调递增的,所以说求[l,r]里面所有数的|运算的结果就行
AC代码:

#include<iostream>
#define LL long long
using namespace std;

const LL mod = 998244353;
const int N = 1000001;
int a[N];
int T, n, q, ans;

struct SegmentTree1 {
int l, r, sum, la, tg;
	#define ls x<<1
	#define rs x<<1|1
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define sum(x) tree[x].sum
	#define la(x) tree[x].la
	#define tg(x) tree[x].tg 
}tree[N << 2];

void pushdown(int x,int val) {
	sum(x)=val;
	tg(x)=val;
}

void pushup(int x){
	sum(x)=sum(ls)|sum(rs);
}

void build(int x,int l,int r) {
	la(x) = 1, tg(x) = 0;
	l(x)=l,r(x)=r;
	if (l(x) == r(x)) {
		sum(x)=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(x);
}

void query(int x, int l, int r) {
	if (l <= l(x) && r >= r(x)) {
		ans|=sum(x);
		return;
	}
	
	if(tg(x)){
	pushdown(ls,tg(x));
	pushdown(rs,tg(x));	
	tg(x)=0;
	}
	
	int mid = (l(x) + r(x)) >> 1;
	if (l <= mid)query(ls, l, r);
	if (r > mid)query(rs, l, r);
	return;
}

void up1(int x, int l, int r,int k) {
	if (l<=l(x)&&r>=r(x)) {
		sum(x)=k;
		tg(x)=k;
		return;
	}
	if(tg(x)){
		pushdown(ls,tg(x)),pushdown(rs,tg(x));
		tg(x)=0;
	}
	int mid = (l(x) + r(x)) >> 1;
	if (l <= mid)up1(ls, l, r,k);
	if (r > mid)up1(rs, l, r,k);
	pushup(x);
}

int main() {
	int m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=0;i<m;i++){
		int op,l,r;
		scanf("%d%d%d",&op,&l,&r);
		if(op==1){
			ans=0;
			query(1,l,r);
			printf("%d\n",ans);
		}
		else {
			int nnum;
			scanf("%d",&nnum);
			up1(1,l,r,nnum);
		}
	}
	return 0;
}

B题-发糖果
思路:把一个数字转换为X进制那么转换后如果是答案要求的‘整数’的话,那么这个数不断去除X剩下的要小于X,即:

bool check(int n,int i){
	while(n%i==0)n/=i;
	if(n<i)return true;//剩下的数要小于进制
	return false;
}

易知:一个数字要是’整数’那么后面就要有0,即那个数字一定必须能被进制整除
即:

if(n%i==0){
			if(check(n,i)){
				ans=min(ans,i);
			}
			if(check(n,n/i)){
				ans=min(ans,n/i);
			}
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long

bool check(int n,int i){
	while(n%i==0)n/=i;
	if(n<i)return true;
	return false;
}

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n,ans;
		scanf("%d",&n);
		ans=n;
		for(int i=2;i*i<=n;i++){
			if(n%i==0){
				if(check(n,i)){
					ans=min(ans,i);
				}
				if(check(n,n/i)){
					ans=min(ans,n/i);
				}
			}
		}
		printf("%d\n",ans);
	}
	
	return 0;
}

H题-牛妹的七夕闯关
思路:一个模拟题
AC代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+10;

struct Node{
	int p,a,b;
	bool operator<(const Node& q)const{
		return p<q.p;
	}
}node[N];
int main(){
	int n,m;
	int ans=0;
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		scanf("%d%d%d",&node[i]. p,&node[i].a,&node[i].b);
	}
	sort(node,node+m);
	ans=node[0].p;
	ans+=max(node[0].a-ans%(node[0].a+node[0].b),0);
	for(int i=1;i<m;i++){
		ans+=node[i].p-node[i-1].p;
		ans+=max(node[i].a-ans%(node[i].a+node[i].b),0);
	}
	if(node[m-1].p<n)ans+=n-node[m-1].p;
	printf("%lld\n",ans);
	return 0;
}

I-永远在一起
一个字符串字串的问题,dp的思想(可以类比LCS这种).
自己写的时候WA了很多次,后来看大佬的代码才明白哪里错了
思路:
从后往前遍历,如果说当前字符是W的话那么他后面必须是F,即当前的数量等于F的数量才能继承下去,如果说后面的字符是0的话那么他当前数量也是0,如果说后面是F的话,且F后面是WFWF这种那么当前数量就要加上WFWF的数量(即4种),即当前数量为4+1=5种,如WFWF=4,WFWFWF=9.
AC代码如下:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+10;

char s[200500];
int len[200500][2];
int main(void)
{
    scanf("%s",s);
    int n=strlen(s),ans=0;
    for (int i=n-1;i>=0;i--)
    {
        if (s[i]=='W'||s[i]=='?') len[i][0]=len[i+1][1]+1;
        if (s[i]=='F'||s[i]=='?') len[i][1]=len[i+1][0]+1;
        int d=max(len[i][0],len[i][1]);
        ans+=d/2;
    }
    printf("%d\n",ans);
    return 0;
}

F过的人很少我就不补了 免得折磨自己嘿嘿
补完题一看时间已经3点半了呜呜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值