Problem - F1 - Codeforces
题目大意:
给定一个长度为n的字符串,相邻的两个减号可以合并成一个加号,判断所有字串当中有多少字串在操作之后(或者不操作)加号和减号的数量一样。
思路:
假定减号数量为啊,加号数量为b,依照题目含义有a - 2*k ==b + k,即a - b ==3k。可能会问,题目要求是说相邻的两个减号才能合并呀,其实,假设他们都不相邻,也也就是像-+-+-+-+这种明显就是也满足条件呀。那么我们现在要做的就是用前缀和预处理一下。其次,对于字符串子串问题,因为起始点和终点在哪都有可能,首先应该想到的就是枚举所有可能性了。
#include<bits/stdc++.h>
using namespace std;
//在没有操作的情况之下,可以把+当成是1,-当成是-1,满足条件的子串在操作之后之和就等于0
// 两个—号转换为一个+号,也就是说a - 2K==b + k,也就是说a - b==3*k
//就算是没有连续的,就好比-+-+-+-+,那同样也是满足条件的
//可以先用前缀和预处理一下前i项之和
void solve()
{
int n;
string s;
int a[3010]={0};
cin>>n>>s;
s=' '+s;
for(int i=1;i<=n;i++)
{
if(s[i]=='+') a[i]=a[i-1]+1;
else a[i]=a[i-1]-1;
}
int ans=0;
for(int i=1;i<n;i++)//时间复杂度可以满足
for(int j=i+1;j<=n;j++)
if((a[j]-a[i-1])%3==0&&a[j]<=a[i-1])
ans++;
cout<<ans<<endl;
return ;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
注:编程解决的其实就是数学问题,可以当作数学问题来看待。找一些关系,列一下等式。
Problem - E - Codeforces
题目大意:
对于给定的n和m,一共有n个箱子需要拉,每一次最多拉m个,那么你至少要拉几次。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
cout<<n/m+(n%m?1:0)<<endl;
return 0;
}
很简单的题目了。
Problem - G - Codeforces
题目大意:
意思就是说,只有两个火车轨道,有N个站台,有一辆火车从1-》N,而另一辆N->1,火车在每一个站台会停留一段时间,运行速度都是1,问两个火车在同一时间在同一站台停留的时间是多长。
思路:
先计算出左边一辆到达每一个站台的时间区间并且记录下来,再用两个变量去记录从右边那个站台出发到达每个站台的时间区间,其实不难发现,两辆火车最多也就只能在一个站台相遇,所以当判断到相交区间值大于等于0就可以退出了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
//int t[N];
ll a[N],x[N];
struct ff
{
ll l;
ll r;
}t[N];
int main()
{
//就是求两辆火车在同一时间一起等的时间,相交的时间
//站的数量,站之间的距离,等待的时间
int n;
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<n;i++) cin>>a[i];//路程
for(int i=1;i<=n;i++) cin>>x[i];//等的时间
t[1].l=0;t[1].r=x[1];
for(int i=2;i<=n;i++)
{
t[i].l=t[i-1].r+a[i-1];//到这里的时间是上一步的结尾+路程
t[i].r=t[i].l+x[i];//结束的时间等于到这里的时间+等的时间
}
a[n]=0;
// int ans=0;
ll enter=0,extra=0;
for(int i=n;i>=1;i--)//到达每个站的时间
{
enter=extra+a[i];
extra=enter+x[i];
if(min(extra,t[i].r)-max(enter,t[i].l)>=0)
{
cout<<min(extra,t[i].r)-max(enter,t[i].l)<<endl;
return 0;
}
}
cout<<0<<endl;
return 0;
}
注:还是要仔细一点,wa了三次,才发现问题,,不应该奥。
Problem - H - Codeforces
题目大意:
就是说对于给定的序列,在1-X的范围之内找到所有的是至少一个数的倍数。
思路:
一开始以为是调和级数那个时间复杂度,就没敢往上写,发现大错特错。
//如果说你这个数是别人的倍数,别人就会笑
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<ll,bool>mp;
int main()
{
ll n,x;
cin>>n>>x;
ll a[25];
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
ll ans=0;
for(int i=1;i<=n;i++)
{
for(ll j=a[i];j<=x;j=j+a[i])
{
if(mp[j]) continue;
else
{
ans++;
mp[j]=true;
}
}
}
cout<<ans<<endl;
return 0;
}
Problem - F - Codeforces
题目大意:
就是说在这些点当中去找四个点组成一个四边形。
思路:
组成一个四边形的首要条件就是说任意三个点都不在同一直线上。
//就是遍历四个顶点,四个当中别任意三个再一条直线上就行
#include<bits/stdc++.h>
using namespace std;
pair<int,int>pi[110];
int n;
bool check(pair<int,int>x,pair<int,int>y,pair<int,int>z)
{
return (x.first-y.first)*(z.second-y.second)==(z.first-y.first)*(x.second-y.second);
}
int main()
{
int n;
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>pi[i].first>>pi[i].second;
int ans=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
for(int k=j+1;k<=n;k++)
for(int l=k+1;l<=n;l++)
{
if(check(pi[i],pi[j],pi[k])) continue;
if(check(pi[i],pi[j],pi[l])) continue;
if(check(pi[i],pi[k],pi[l])) continue;
if(check(pi[j],pi[k],pi[l])) continue;
ans++;
}
cout<<ans<<endl;
return 0;
}
注:有想法就去试一下,万一对了呢。
Problem - J - Codeforces
题目大意:
就是说找到第k大的子序列。
思路:
bfs,遍历所有情况。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
string s;
array<int, 26>cnt;
};
ll ans;
string s;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,k;
int tot=0;
cin>>n>>k>>s;
array<int,26>cnt;
for(int i=0;i<26;i++) cnt[i]=0;
for(char ch:s) cnt[ch-'a']++;
queue<node>q;
q.push({"",cnt});
while(!q.empty())
{
const string s=q.front().s;
auto cnt=q.front().cnt;
q.pop();
for(int i=0;i<26;i++)
{
if(cnt[i])
{
if(++tot==k)
{
cout<<s<<char('a'+i);
return 0;
}
auto cc=cnt;
cc[i]--;
q.push({s+char('a'+i),cc});
}
}
}
}
注:C++ array