2021-10-27CCPC Training 补题

CCPC Training 补题

我校21-10-31新疆ccpc省赛淘汰赛
题目来源(杭电的oj)
Overview

A

Baby volcano is helping his CCPC coach preparing a new CCPC training contest.

Descriptiondescription

没看懂

input and output

请添加图片描述

sample

请添加图片描述

think

当时以为很难,但是看到大家就都能ac这一题就按照sample推了一下就推出来了。
是给一个字符串找出里面重复最多的元素,定义一个map,sovle。

code

#include <iostream>
#include <map>
using namespace std;
int main()
{
	int t;
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		char a[100000+5];
		int max=0;
		map<char,int> cnt;
		int j=0;
		//while()
		cin>>a;
		for(int j=0;a[j]!='\0';j++)
		{
			cnt[a[j]]++;
			if(cnt[a[j]]>max) max=cnt[a[j]];
		}
		cout<<"Case #"<<i<<": "<<max<<endl;
	}
	return 0;
}

C

description

In the country of Infinity , there is a strange road. This road only has a starting point, but no end. Since this road is infinite, there are also countless street lights.请添加图片描述
意思是一条公路无线远,每隔一定距离有个路灯,所以会有无穷多个路灯。第一个路灯编号为1,第二个路灯编号为2,一直下去。。。。
当一个路灯编号为偶数时,x与x/2连。
当一个路灯编号为奇数数时,y与3y+1连。
现在k先生站在编号为n 和编号为n+1的路灯之间,问他切一刀最多能切多少根电线。请添加图片描述

think

边界问题 可以证明论n为奇数还是偶数时 因为法则一(x)通过的电线数,必然为 n-n/2;
而因为法则二(y)通过的电线则会因为n奇偶性而改变。
我是这样想的,假定通过的电线范围在n~(n-1)/3 而这里面有有几个奇数是所要在在意的。
并不要考虑(n-1)/3 ,因为当他满足这个时是刚好不过,所以去除(无论是否整除)。
所以 假设得到的为 2 3 4 5 6 7 8 则 2 3|4 5|6 7| 8 满足。
假设得到的为 2 3 4 5 6 7 8 9 则 2 3|4 5|6 7|8 9| 则要加一除以二。所以

		sum=n-n/2;//x
		if(n%2==0)//y
		{	
			sum=sum+(n-(n-1)/3)/2;
		}
		else
		{
			sum=sum+(n-(n-1)/3+1)/2;

code

#include <iostream>
using namespace std;
int main()
{
	int t;
	cin>>t;
	for(int i=0;i<t;i++)
	{
		int n,sum=0;
		cin>>n;
		sum=n-n/2;//x
		if(n%2==0)//y
		{	
			sum=sum+(n-(n-1)/3)/2;
		}
		else
		{
			sum=sum+(n-(n-1)/3+1)/2;
		}
		cout<<sum<<endl;
	}
	return 0;
}

D

//刚刚发现好像可以直接用链接,所以只要点上面那个二级标题,就可以直接去看原题了。
There is a robot that can move by receiving a sequence of commands.
请添加图片描述
就一个机器人,可以上下左右移动,问连续子序列有几个可以从原点出发然后再回到原点。

think

把全部题读了一遍时,以为是签到题,用穷举两层遍历试了一遍,time limit。然后又想的是括号匹配问题,想用动态规划解决,但是想不出了。后来看了一下别人代码,懂了。
看了两个思想都特别好。模拟机器人的路径,在什么时候可以回原点呢?只要过重复的点就行了,定义一个map<pair<int,int>,int>。没过一个点都ans都加上当前的map,再map++。

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

typedef long long ll;
typedef pair<int,int>PII;

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
        map<pair<int,int>,int>mp; 
        int n;
        string s;
		cin>>n >>s;
		mp[{0,0}]=1;
		ll res=0,p=0,q=0;
		for(int i=0;i<s.size();i++)
		{
			if(s[i]=='U') p++;
			else if(s[i]=='R') q++;
			else if(s[i]=='L') q--;
			else p--;
			res+=mp[{p,q}]; 
			mp[{p,q}]+=1;
		}
		cout <<res <<endl;
	}
	return 0;
}

另一个算法我感觉时间复杂度和空间复杂度优于前一个算法,但是较为难读。用一个一维来表示了二维。

#include <iostream>
#include <map>
using namespace std;
long long sum[100005];

map<char, int> m;
int main()
{
	int t;
	cin >> t;
	m['U'] = 1;
	m['D'] = -1;
	m['L'] = -100005;
	m['R'] = 100005;
	while (t--)
	{
		char s[100005];
		map<long long, int> S;
		int n;
		cin >> n;
		cin >> s;
		S[0] = 1;
		long long ans = 0;
		for (int i = 0; i < n; i++)
		{
			sum[i] = sum[i - 1] + m[s[i]];
			if (S[sum[i]])
			{
				ans += S[sum[i]];
			}
			S[sum[i]]++;
		}
		cout << ans << endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值