“陌上人如玉,公子世无双!”|

xxj112

园龄:2年10个月粉丝:11关注:18

Codeforces Round #885 (Div.2) Editorial(B~D)

B - Vika and the Bridge

题意:从桥的一边走到另一边,每次只能踩在相同颜色的木板上,并且有一次操作,可以修改期中一个模板的颜色。 问那种走法,跨过模板的最大值最小。
思路:首先可以统计出选择每种颜色的,跳过木板的的个数,如果不能修改颜色,那么答案一定是每个颜色所对应的最大值的最小值,因为现在可以修改,所以对于每种颜色来说,就不一定是最大值了。最大值/2,与次大值比较,k值很小,二维度vector存,sort排序,比较最大值/2和次大值即可
代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define max(ver1,ver2) (ver1>ver2?ver1:ver2)
#define min(ver1,ver2) (ver1>ver2?ver2:ver1)
#define lowbit(ver) ver&(-ver)
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define ull unsigned long long
#define debug(ver) cout<<#ver<<" = "<<ver<<"\n"
#define debug2(ver,ver2) cout<<#ver<<" = "<<ver<< "  " << #ver2 << " = " << ver2 <<"\n"
#define eps 1e-9
#define pb push_back
using namespace std;

const int N = 1e6 + 10, M = N * 4, mod = 1e9 + 7;

int n, m, k;
int a[N];
int c[N];
void solve()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    a[0]=0;
	for(int i=0;i<=k;i++) c[i]=0;
	vector<int> ve[k+1]; //开里面不用初始化
	for(int i=1;i<=n;i++) //统计对应颜色所跨越木板个数
	{
		ve[a[i]].push_back(i-c[a[i]]-1); 
		c[a[i]]=i;
	}
	int ans=n+1;
	for(int i=1;i<=k;i++)
	{
		ve[i].push_back(n-c[i]); //对应颜色最后一块木板,到终点的距离。
		sort(ve[i].begin(),ve[i].end() );
		int x=ve[i][ve[i].size()-1]; //最大值
		int y=ve[i][ve[i].size()-2]; //次大值
		 x=max(y,x/2);
		 ans=min(ans,x);
	}
	cout<<ans<<"\n";


}
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int T=1;
    // scanf("%lld",&T);
     cin>>T;
    while(T--)
    {
        solve();
    }
    
    return 0;
}

C Vika and Price Tags
题意:判断是都可以生成全零数组。
思路:先打单独判断一位数,打表找规律,发现 多次操作后一定会出现 0 x x 0 x x 0 ,所以只需要找到每个数第一次出现0的位置即可。的到数组c,如果c中数差值都是三的倍数,则能变成全零数组。
代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define max(ver1,ver2) (ver1>ver2?ver1:ver2)
#define min(ver1,ver2) (ver1>ver2?ver2:ver1)
#define lowbit(ver) ver&(-ver)
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define ull unsigned long long
#define debug(ver) cout<<#ver<<" = "<<ver<<"\n"
#define debug2(ver,ver2) cout<<#ver<<" = "<<ver<< "  " << #ver2 << " = " << ver2 <<"\n"
#define eps 1e-9
#define pb push_back
using namespace std;

const int N = 1e6 + 10, M = N * 4, mod = 1e9 + 7;

int n, m, k;
int a[N];
int c[N];
int b[N];
int ck(int x,int y)//返回第一次出现零的位数
{
	if(x==y) return 1; //相等下一位一定是0
	if(x<y)
	{
		return ck(y,abs(x-y))+1; //下次 y 一定大于 x
	}
	
	else 
	{
		if(x/y<=2) // 
		{
		
			return ck(y,abs(x-y))+1;
		}
		else //这是一个规律,每次没经过三次,相当于 x值减去 两个 y
		{
			int w=x/y;
			w=w/2;
			return ck(x-w*(2*y),y)+3*w;
			
		}
		
	}
}
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    
    int tot=0;
   	for(int i=1;i<=n;i++)
   	{
   		if(a[i]==0&&b[i]==0) continue; //0 0 一直是零不考虑
   		else if(a[i]==0) c[tot++]=1; //特判
   		else if(b[i]==0) c[tot++]=2; // 
   		else
   		c[tot++]=ck(a[i],b[i])+2; //加二表示前两位
	}
	int flag=1;
	for(int i=1;i<tot;i++)
	{
		if(abs(c[i]-c[i-1])%3!=0) flag=0;
	}
     if(flag) cout<<"YES\n";
     else cout<<"NO\n";


}
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int T=1;
    // scanf("%lld",&T);
     cin>>T;
    while(T--)
    {
        solve();
    }
    
    return 0;
}

D Vika and Bonuses
题意 :每次有两种操作 ,让s+=s%10,k--, 或者让答案 ans+=s;共k此操作,输出最大答案。
思路: 数据很大 ,还是多组输入,考虑找规律,发现 最后一位多次操作后,会进入两种循环,2 4 8 6 2 4 8 6,或者 0 0 0 0 0
贪心知道,如果要操作一只能先进行,
第二种类很好考虑,见代码
循环很小,所以可以考虑以每一个起点偶数为起点 ,看进行多少次循环答案最大, 设进行x此操作,则 ans=(s+x20)(k-4x),一元二次,向下,有最大值。 注意一点,x可能为数,而转化成整形是向下取整,所以求得后。也要考虑下x+1
代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N = 2e3+7;
int a[N];
int ck(int s,int k) //判断 2 4 8 6 一个循环s+20,多少次循环后值最大。 
{
	int ans=s*k; //不操作
	int a,b,c; //一元二次方程系数
	a=-80;
	b=20*k-4*s;
	c=s*k;

	int x=-b/(2*a);
	x=min(x,k/4) ; //x最大不超出哦 k/4;

	if(x>0)
	{
		ans=max(ans,a*x*x+b*x+c);
	}
	x=min(x+1,k/4);//多算一步,防止误差(因为x默认成整数了)
	if(x>0)
	{
		ans=max(ans,a*x*x+b*x+c);
	}
	return ans;
}
void solve()
{	
	int s,k;
	cin>>s>>k;
	int ans=s*k; //只选择操作一
	if(s%10==5)
	{
		ans=max(ans,(s+5)*(k-1));
	}
	else if(s%10>0)
	{
		if(s%2==1) //一定要让最后以为为偶数,才能进入循环
		{
			s+=s%10;
			k--;
		}
		for(int i=1;i<=4;i++) //分别以2 4 8 6 为循环起点
		{
			ans=max(ans,ck(s,k));
			s+=s%10;
			k--;
		}
	}
	cout<<ans<<"\n";
	
}	
signed main() {
	cin.tie(0)->sync_with_stdio(false);
	int t=1;
	cin>>t;
	while(t--)
	{
		solve();
	}
	return 0;
}

本文作者:xxj112

本文链接:https://www.cnblogs.com/xxj112/p/17559466.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xxj112  阅读(112)  评论(4编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 椿 沈以诚
椿 - 沈以诚
00:00 / 00:00
An audio error has occurred.

作词 : 沈以诚

作曲 : 沈以诚

恍惚间 浸透了回忆

漫漫的回忆 存在的回忆

只看见 遗忘的笑脸

纯洁的笑脸不在身边

想实现 从前的诺言

不轻的诺言 和你的诺言

却描绘 无期限的诗

由寓意的诗刻画的线

乔木落叶 告诉我时间变迁

你仍旧倚靠石头看岁岁年年

惊觉两鬓霜白长叹一声哀怨

也不过匆匆弹指间

不在意我存在你心里面

只记得当时没有那么远

一眼朝如青丝暮成雪

美梦惊你不在眼前

我想给你一颗我的眼

倒映着曾拾起的缘

若皆是一场镜花水月

也不想忘记你的颜

唯一心愿

恍惚间 浸透了回忆

恍惚间 浸透了回忆

漫漫的回忆 存在的回忆

只看见 遗忘的笑脸

纯洁的笑脸不在身边

想实现 从前的诺言

不轻的诺言 和你的诺言

却描绘 无期限的诗

由寓意的诗刻画的线

乔木落叶 告诉我时间变迁

你仍旧倚靠石头看岁岁年年

惊觉两鬓霜白长叹一声哀怨

也不过匆匆弹指间

不在意我存在你心里面

只记得当时没有那么远

一眼朝如青丝暮成雪

美梦惊你不在眼前

我想给你一颗我的眼

倒映着曾拾起的缘

若皆是一场镜花水月

也不想忘记你的颜

唯一心愿

点击右上角即可分享
微信分享提示