2019summer系列 第五场

博客主要围绕 CodeForces 1000A - D 题目展开。1000A 题解法暴力;1000B 题需计算初始和插入点的亮灯时间;1000C 题可用差分、离散化,也可将区间看成括号处理;1000D 题给出相关参考博客。还提及 EFG 题难度大,后续单独研究发布。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://vjudge.net/contest/310495#overview
可以说是十分划水了。养生快乐。

CodeForces 1000A


一个写法非常暴力的题。反正我是很暴力。嗯嗯~

#include<bits/stdc++.h>
using namespace std;
int n,p[12],f[12];
string s; 

int main(){
	cin >> n;
	memset(p,0,sizeof p);
	memset(f,0,sizeof f);
	for(int i = 0;i < n;i ++) {
		cin >> s;
		if(s=="S") p[1] ++;
		if(s=="M") p[2] ++;
		if(s=="L") p[3] ++;
		if(s=="XS") p[4] ++;
		if(s=="XL") p[5] ++;
		if(s=="XXS") p[6] ++;
		if(s=="XXL") p[7] ++;
		if(s=="XXXS") p[8] ++;
		if(s=="XXXL") p[9] ++;
	}
	for(int i = 0;i < n;i ++){
		cin >> s;
		if(s=="S") f[1] ++;
		if(s=="M") f[2] ++;
		if(s=="L") f[3] ++;
		if(s=="XS") f[4] ++;
		if(s=="XL") f[5] ++;
		if(s=="XXS") f[6] ++;
		if(s=="XXL") f[7] ++;
		if(s=="XXXS") f[8] ++;
		if(s=="XXXL") f[9] ++;
	}
	int cnt = 0,tmp;
	//for(int i = 1;i <=3;i ++)  p[i] -= f[i];
	for(int i = 1;i <= 9; i ++)  p[i] -= f[i];
	for(int i =1;i <= 9; i ++){
		if(p[i]>0) cnt += p[i];
	}
	cout <<cnt;
    return 0;
}

CodeForces 1000B


首先计算出初始时总的亮灯时间,然后计算出在每个点插入的亮灯时间(总时间是一样的,总亮灯时间-当前点为止总亮灯时间=后边的亮灯时间,后边的时间-后边的亮灯时间=后边的灭灯时间)。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m;
int a[maxn];
int main(){
	cin>>n>>m;
	for (int i=1;i<=n;i++){
		cin>>a[i];
	}	
	int lon=0,loff=0;  //总亮灯、灭灯时间
	a[0]=0;
	for (int i=1;i<=n;i++){
		if (i%2==1) lon+=a[i]-a[i-1];
		else loff+=a[i]-a[i-1];
	}
	a[n+1]=m;
	if (n%2==1) loff+=m-a[n];else lon+=m-a[n];
	int maxs=lon; 
	int x=0,y=0; //当前位置的总亮灯时间、灭灯时间
	for (int i=0;i<=n+1;i++){
		if (i!=0){
			if (i%2==1)
				x+=a[i]-a[i-1];
			else 
				y+=a[i]-a[i-1];
		}
		if ((a[i]-1>a[i-1]&&i!=0) || (a[i]+1<a[i+1]&&i!=n+1)){
			if (i%2==1)
				maxs=max(maxs,x-1+loff-y);
			else maxs=max(maxs,x+1+loff-y);
		}
	}
	cout<<maxs<<endl;
	return 0;
}

CodeForces 1000C


dalao们说是差分、离散化。可以用map实现。可哈希,
但是某只神奇的lan是这么讲的:
把区间看成括号,然后它其实就是这样的:
()(( ( )() ))( ( ( ))()())
储存的时候就存每半个括号的位置及属性。然后按位置排序。
然后对于每个位置处理一下四种情况(tmp代表左右括号抵消后,净‘(’的个数):
((,)),(),)(。

  1. ((:不用算后边那个点,因为它应该是tmp+1
  2. )):不用算后边那个点,因为它应该是tmp-1。
  3. ():要算这两个括号的端点,要+1。
  4. )(:两个括号的端点都不要算。-1。
#include<bits/stdc++.h>
using namespace std;
struct node{
	long long x;
	bool z;
}a[100500<<2];
long long int n,cnt;
long long int mm[100500<<1];
long long l,r;
bool cmp(const node&a,const node &b){
	if(a.x==b.x) return a.z>b.z;//我觉得好像不用这一句也可
	return a.x<b.x;
}
int main(){
	cin >> n;
	cnt = 0;
	memset(mm,0,sizeof mm);
	for(int i = 1;i<= n;i ++){
		scanf("%lld%lld",&l,&r);
		a[cnt].x = l;
		a[cnt].z = true;
		cnt ++;
		a[cnt].x = r;
		a[cnt].z = false;
		cnt ++;
	}
	sort(a,a+cnt,cmp);
	long long int tmp,lp,np;
	tmp = 1;
	lp = a[0].x;
	for(int i = 1;i < cnt; i ++){
		np = a[i].x;
		if(a[i].z==true)
			if(a[i-1].z == true) mm[tmp] += np-lp;
			else mm[tmp] += np-lp-1;
		else
			if(a[i-1].z == true) mm[tmp] += np-lp+1;
			else mm[tmp] += np-lp;
		if(a[i].z==true) tmp ++;
		if(a[i].z==false) tmp --;
		lp = np;
	}
	for(int i = 1;i<n;i ++){
		printf("%lld ",mm[i]);
	}
	printf("%lld",mm[n]);
    return 0;
}

CodeForces 1000D


https://blog.csdn.net/deerly_/article/details/80963405
这位dalao说得太对啦。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 100;
const int mod = 998244353;
ll dp[maxn], data[maxn];//dp记录从当前位置开始的好数列的个数 
ll c[maxn][maxn];//组合数 

int main(){
   int n;
   scanf("%d", &n);
   for(int i = 0; i <= n; i++) {
      c[i][0] = c[i][i] = 1;
      c[i][1] = i;
   }
   for(int i = 1; i <= n; i++) {
      for(int j = 1; j <= n; j++) {
         c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod; //杨辉三角防爆组合数 
      }
   }
   for(int i = 1; i <= n; i++) {
       scanf("%lld", &data[i]);
   }
   dp[n + 1] = 1;//其实我是举例得出的。。
   for(int i = n; i > 0; i--) {//从后往前推出dp【i】,因为实际有用的是后边的
      if(data[i] <= 0) continue; //好的数列开头大于 0 
      for(int j = data[i] + i + 1; j <= n + 1; j++) { //找到一个可以接上的开头
          dp[i] = dp[i] + (c[j-i-1][data[i]] * dp[j]) % mod;
          dp[i] %= mod;
      }
   }
   ll sum = 0;
   for(int i = 1; i <= n; i++)
    sum = (sum + dp[i]) % mod;
   printf("%lld\n", sum);
}


EFG太难啦。。。等我回来研究研究,单独发吧。。据说。。。。。
E是缩点+树的直径。。。
F是线段树+离线,或者主席树。。。
G是树形dp+LCA。。








btw,xhx生日快乐!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值