CCPC Training 补题
我校21-10-31新疆ccpc省赛淘汰赛
题目来源(杭电的oj)
A
Baby volcano is helping his CCPC coach preparing a new CCPC training contest.
Description
没看懂
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;
}