内容持续更新中

Codeforces Round #809 (Div. 2)

 

Problem - A - Codeforces 

         给了t个询问,n个数Ai,又给了一个数为m,原来字符串为一连串的B,有两个操作第一个操作使第Ai个变为A,第二个操作使(M+1-Ai)变为A,使其字典序最小,肯定是比一下看那个在前面,记录一下即可。

1
4 5
1 1 3 1

       注意的使我们要判断一下是否有重复操作进行了操作1以后,再次遇到这个数时进行操作二,先进行2时再进行1。

查看代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char a[60];
bool st[60];
int b[60];
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n,m;
        cin >> n>>m;
        for(int i=1;i<=m;i++) 
        {
        	a[i]='B';
        	st[i]=false;
		}
        for(int i=1;i<=n;i++) 
        {
        	cin >> b[i];
		}
        for (int i = 1; i <= n; i ++ )
        {
            if(b[i]<=m+1-b[i]&&!st[b[i]]) 
            {
                a[b[i]]='A';
                st[b[i]]=true;
            }
            else if(b[i]>m+1-b[i]&&!st[m+1-b[i]])
            {
                 a[m+1-b[i]]='A';
                 st[m+1-b[i]]=true;
            }else if(st[b[i]])
            {
                a[m+1-b[i]]='A';
            }else if(st[m+1-b[i]])
            {
                a[b[i]]='A';
            }
        }
        for (int i = 1; i<=m; i++ )
        cout << a[i];
        cout << endl;
    }
    return 0;
}

 

Problem - B - Codeforces 

       这题真的是道好题,给了n个数Ai,每个数代表了一个颜色,当前Ai只能放在前一个的左右两边或者上边,判断一下每种颜色能达到的最大高度。首先是数据转图形。

7
1 2 3 1 2 3 1
    
input:
3 2 2 0 0 0 0 

  可以发现只要中间差两个数就可以形成高塔,很好wa了。再讨论离得更远些。

     

相离偶数个就可以,但是我们碰到了极端情况也就是最优解的选取,怎样判断最优解,这里给一个小证明即从头开始取即是最优解。

6
4 2 2 2 4 4

查看代码:
#include<iostream>
using namespace std;
const int N=1e5+10;
struct
{
	int x;
	int y;
}e[N];
bool st[N];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			int z;
			cin>>z;
			if(!st[z])
			{
				e[z].x=i;
				e[z].y++;
				st[z]=1;
			}else if((i+1-e[z].x)%2==0)
			{
				e[z].x=i;
				e[z].y++; 
			}
		}
		for(int i=1;i<=n;i++)
		cout<<e[i].y<<' ';
		cout<<endl;
		for(int i=1;i<=n;i++)
		{
			 st[i]=0; 
			 e[i].y=0;
		}
	}
	return 0;
 }

 

Problem - C - Codeforces

        给了n个数Ai,代表每个位置柱子的初始高度,可以进行操作使柱子的高度加一使其cool(Ai-1<Ai&&Ai+1<Ai)既是山峰,求每个样例最多山峰的最小操作数。

3
2 1 2
6
3 1 4 5 5 2
8
4 2 1 3 5 3 6 1

 


 

当长度为奇数时

比如第一个样例,下标i为1-n,那么下标为偶数的点必需是凉爽点,这是直接加起来就行

当长度为偶数时

可以发现第2,3个,第4,5个,第6,7个.....中选一个作为凉爽点,而且不能有相邻

如果第3个为凉爽点,那么后面的就一定是5,7,9...
如果第5个为凉爽点,那么后面的就一定是7,9,11...

也就是从某一处开始选的是右边奇数的,那么后面一定都是选右边奇数,而前边一定都是选左边偶数的

那么记录选左边的从前到后的和x[i],以及选右边的从后到前的和y[i]

答案就是max(x[i]+y[i+1])

查看代码
 #include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define inf (1ll<<52)
const int N=1e5+10;
long long  a[N];
long long c[N];
long long d[N]; 
int main()
{
	int t;
	scanf("%d",&t);
    while(t--)
	{
	 int n;
 	 scanf("%d",&n);
	 for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	 for(int i=2;i<=n-1;i+=2)
	{
		    c[i]+=c[i-2]+max(0ll,max(a[i-1],a[i+1])-a[i]+1);
	}
	if(n&1)
	{
		printf("%lld\n",c[n-1]);
	  memset(c,0,sizeof c);
	  memset(d,0,sizeof d);
	  memset(a,0,sizeof a);
	    continue;
	}
    for(int i=n-1;i>1;i-=2) 
    d[i]=d[i+2]+max(0ll,max(a[i-1],a[i+1])-a[i]+1);
    long long  res=inf;
    for(int i=0;i<=n-1;i+=2)
    {
    	if(i>=n-2) res=min(res,c[i]);
    	else res=min(res,c[i]+d[i+3]);
	}
	  printf("%lld\n",res);
	  memset(c,0,sizeof c);
	  memset(d,0,sizeof d);
	  memset(a,0,sizeof a);
	 } 
	return 0;
 } 

  后话:b题有思路但是感觉自己做不出来就没有去做,其实仔细想想是能做出来的,思路不是很难,还是在于特殊情况的判定和自己做题时的状态。c题题解的思路很好用前缀和取处理,顺序处理偶数,逆序处理的是奇数。然后从头开始循环判断当前处理,c[i]与d[i+3] 中间是相隔两个所以是d[i+3]。注意:0 long long 表示为 0ll。

posted @   Armored_bear  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示