Codeforce edu 63 div2 题解报告

水平有限,只打了三题比较简单的模拟题;

a.题目大意:任意倒转两个字符使字典序更小,找到字典序相反的两个,直接倒转就好,复杂度O(n);

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{
	int n;
	scanf("%d",&n);
	string s;
	cin>>s;
	for(int i=1;i

b.题意,给出一个连续的数字,数字长度>13,V和P轮流删除一个数,当删除到是十一位时,停止操作。然后问

V先操作时,最后的数字是否以8开头。是则输出yes否则no;

题解:我是直接模拟了,贪心,V肯定删除从左到右第一个不是8的数,P肯定删除从左到右最先出现的8;

        还有一种做法是统计最后10个数字之前的8的个数,看看操作轮数是否大于8的个数,大于则no;

      当时没想到,就直接模拟了,所以代码比较丑

   

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{   int n;
   scanf("%d",&n);
   bool vis[100005];
   memset(vis,true,sizeof(vis));
   vectorq;
	string s;
	cin>>s;
	int flag=1;
    int q1=0,q2=0;
    
    for(int i=0;i<(s.size()-11)&&q1

c

题意:有一个闹钟,给出n个时间,和m个时间间隔。要求你选择一个开始的时间y与一个间隔p;

那么从y开始每隔p个时间间隔就闹钟会响一次,需要在给出的n个时间点上,闹钟都会想;

题解:找出n个时间的差,然后对差取最小公因数g,然后从间隔中判断,是否存在一个间隔p,使得g%p==0;

输出任意答案;

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
const int maxn=3e5+10;
ll arr[maxn];
ll brr[maxn];
ll crr[maxn];
ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a;
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	ll gg;
	int cnt=0;
	up(i,1,n)
	{
		if(i==1)scanf("%I64d",&arr[i]);
		else
		{   scanf("%I64d",&arr[i]);
		    crr[++cnt]=arr[i]-arr[i-1];
		}
	}
	if(cnt==1)
	{
		gg=crr[1];
	}
	else 
	{
	gg=gcd(crr[1],crr[2]);
	up(i,3,cnt)
	{
		gg=gcd(crr[i],gg);
	}
   }
	int flag=0;
	up(i,1,m)
	{
		scanf("%I64d",&brr[i]);
		if(gg%brr[i]==0)
		{
			flag=i;
		}
	}
	if(flag)
	{
		    cout<<"YES"<

d题

题意,给出一个n,m;与长度为n的数组

可以进行一个操作,就是对于长度为n的数组的连续子序列可以乘上m。然后再求,最大子序列和;

这题用DP的思想,考虑当前位置状态,一共有三种;

1.处于处理区间前

2.处于处理区间中

3.处于处理区间外

所以需要3个dp数组,dp[i][3]//i表示从1开始的区间到i的最大子序列和

然后可以得出下面的状态方程

dp[i][0]=max(dp[i-1][0],0ll)+a[i];//0状态表示可以开始新的处理
dp[i][1]=max(dp[i-1][0],max(dp[i-1][1],0))+a[i]*1ll*m//1状态表示处于处理的区间
dp[i][2]=max(max(dp[i-1][0],d[i-1][2]),max(dp[i-1][1],0ll))+a[i];状态表示处理完毕,即后面不可处理

注意的就是,当当前区间的最大子序列和小于0的时候,我们可以直接取0,以及在max中,数据类型必须相同;

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
const int maxn=3e5+10;
ll dp[maxn][3];//i表示从1开始的区间到i的最大字段和
ll arr[maxn];
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	up(i,1,n)cin>>arr[i];
	ll ans=0;
	up(i,1,n)
	{
		dp[i][0]=max(dp[i-1][0],0ll)+arr[i];//0状态表示可以开始新的操作
		dp[i][1]=max(max(dp[i-1][1],0ll),dp[i-1][0])+arr[i]*m;//1状态表示处于倒转的区间
		dp[i][2]=max(max(dp[i-1][0],0ll),max(dp[i-1][1],dp[i-1][2]))+arr[i];//2状态表示倒转完毕,即后面不可倒转
		ans=max(ans,dp[i][0]);
		ans=max(ans,dp[i][1]);
		ans=max(ans,dp[i][2]);
	}
	cout<

 

后面的···不会了,努力补题ing!!!

 

你可能感兴趣的:(cf)