CF665

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值