CF EDU12
A. Buses Between Cities
思路
时间看着很烦, 所以我们可以把时间给统一下。
那么, 我们用分钟表示时间, 比如05:00就可以表示为
5
×
60
=
300
5 \times 60 = 300
5×60=300
那么, 仔细思考一下, 就会发现其实我们的司机从A开到B时是一个时间段, 长度为ta。
那么他会碰到的公交车其实是这样的:1.他在司机出发前到达 2.他在司机到达前出发。
把这两种情况用式子表示一下, 公交车从5:00开始每b分钟发一趟。
可以看出, 其实a是没有用的。。。
代码
#include<bits/stdc++.h>
using namespace std;
int a, ta;
int b, tb;
int h, m;
int ans = 0;
int main()
{
cin >> a >> ta;
cin >> b >> tb;
cin >> h;
getchar();
cin >> m;
int nowl = h * 60 + m;
int nowr = nowl + ta;
for(int l = 300; l <= 1439; l += b)
{
int r = l + tb;
if(r > nowl && l < nowr)
{
ans++;
//cout << l << " " << r << endl;
}
}
cout << ans << endl;
return 0;
}
B. Shopping
思路
读了半天题没读懂。。。
总的来说, 就是加权值, 放开头,然后在把所有位置往后后移。
因为数据很小, 所以暴力即可。
代码
#include<bits/stdc++.h>
using namespace std;
int p[110];
int n, m, k;
int ans = 0;
int num;
int main()
{
cin >> n >> m >> num;
for(int i = 1; i <= num; i++)
{
cin >> p[i];
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
int x;
cin >> x;
int k;
for( k = 1; k <= num; k++)
{
if(p[k] == x)
{
break;
}
}
ans += k;
for(int l = k; l >= 2; l--)
{
p[l] = p[l-1];
}
p[1] = x;
}
}
cout << ans << endl;
return 0;
}
C. Simple Strings
思路。
这个题应该是6道中最简单的。
如果有连续的一段相等字符组成的字符串。
显然, 无论对于长度为奇或偶的字符串, 让其隔一个变一个总是最优的。
所以我们从第2个字符向前遍历, 同时判断是否与前面相等, 如果相等, 就要改变。
注意, 改变的话还不能改变成与后面那个一样的字符。
对于找字符枚举即可。
#include<bits/stdc++.h>
using namespace std;
char s[200010];
int main()
{
scanf("%s", s+1);
int len = strlen(s+1);
//cout << len << endl;
cout << s[1];
for(int i = 2; i <= len; i++)
{
if(s[i] == s[i-1])
{
for(int j = 0; j <= 25; j++)
{
char ch = 'a' + j;
if(ch != s[i-1] && ch != s[i+1])
{
s[i] = ch;
break;
}
}
}
cout << s[i];
}
return 0;
}
大佬做法
在大佬眼中, 一个位置改变的话, 只需要不予他前面和后面相同即可, 所以不需那么麻烦, 只填’a’, ‘b’, 'c’即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
for(int i=1; i+1<str.size(); i++){
if(str[i] == str[i-1]){
if(str[i] != 'a' && str[i+1] != 'a')
str[i] = 'a';
else if(str[i] != 'b' && str[i+1] != 'b')
str[i] = 'b';
else
str[i] = 'c';
}
}
if(str.size() > 1 && str[str.size()-1] == str[str.size()-2] && str[str.size()-1]!='a')
str[str.size()-1] = 'a';
else if(str.size() > 1 && str[str.size()-1] == str[str.size()-2])
str[str.size()-1] = 'b';
cout<<str<<endl;
return 0;
}
D. Simple Subset
思路
主要是探究如果要让a+b为质数, a和b的性质。
首先, a+b互质, 那么a+b必为奇数(和2)。
那么要求这个数列中任意两个数相加都为奇数(和2)。
显然, 除1外, 任意三个数不管奇偶的和都为偶数。
所以, 这个数列如果没有1, 最大长度为2。
下面来考虑1的情况:
首先1肯定是要全拿的, 无论拿多少个1, 他们之间内部最多形成2.
在考虑1与其他数。
显然(1+要选的数)要为质数。
那么, 这个要选的数就为偶数, 且加上1后的奇数的因子只有他自己和1
如果没有, 全选1即可。
否则, 选1奇数1偶数。
最后, 是在没得选了, 随便拿1个数。
贪心;
#include<bits/stdc++.h>
using namespace std;
int n;
int a[1010];
int cnt1 = 0;
int flag = 0;
int ou[1010];
int ji[1010];
int p_ou;
int p_ji;
bool check(int x)
{
for(int i = 2; i * i <= x; i++)
{
if((x % i) == 0)
{
return false;
}
}
return true;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
if(a[i] == 1)
{
cnt1++;
}
else
{
if(a[i] % 2 == 0)
{
if(check(a[i] + 1))
flag = a[i];
ou[++p_ou] = a[i];
}
else
{
ji[++p_ji] = a[i];
}
}
}
if(cnt1 && flag)
{
cout << cnt1 + 1 << endl;
for(int i = 1; i <= cnt1; i++)
{
cout << 1 << " ";
}
cout << flag << endl;
}
else if(cnt1 >= 2)
{
cout << cnt1 << endl;
for(int i = 1; i <= cnt1; i++)
{
cout << 1 << " ";
}
}
else
{
for(int i = 1; i <= p_ou; i++)
{
for(int j = 1; j <= p_ji; j++)
{
int now = ou[i] + ji[j];
//cout << now << endl;
if(check(now))
{
cout << 2 << endl;
cout << ou[i] << " " << ji[j] << endl;
return 0;
}
}
}
cout << 1 << endl << a[1] << endl;
}
return 0;
}
E TLE
F WA