牛客周赛 Round 10 A ~ C

 比赛链接



比赛链接

A

双指针

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'

using namespace std;

typedef pair PII;
typedef pair PDI;
typedef long long ll;

const int N = 100010;

int a[N];

int main()
{
	IOS
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++)cin >> a[i];
	
	int ans = 0, res = 1;
	for(int i = 2; i <= n; i ++)
	{
		if(abs(a[i] - a[i - 1]) <= 1)
		{
			res ++;
		}
		else
		{
			ans = max(ans, res);
			res = 1;
		}
	}
	ans = max(ans, res);
	
	cout << ans << endl;
	
	return 0;
}

B

全排列,手动dfs全排列每次去重必须要用到map或者unordered_map,用了就会超时,不知道有没有不用map的去重全排列写法,反正我写的确实有点歪门邪道,数据再强一点就被卡了

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'

using namespace std;

typedef pair PII;
typedef unsigned long long ull;
typedef long long ll;

const int P = 131;

int ans, n;
unordered_map mp;
bool st[20];
char s[20];
string p;

void dfs(int u)
{
	if(u == n)
	{	
		int f = 1;
		for(int i = 0; i < n - 1; i ++)
		{
			if(p[i] == p[i + 1])
            {
                f = 0;
                break;
            }
        }
        if(!f) return;
        if(mp[p])return;
        mp[p] = 1;
		ans += f;
        return;
	}
	
	for(int i = 0; i < n; i ++)
	{
		if(!st[i])
		{
			st[i] = true;
			p[u] = s[i];
			dfs(u + 1);
			st[i] = false;
		}
	}
}

int main()
{
	IOS
	cin >> s;
	n = strlen(s);
    for(int i = 0; i < n; i ++)p.push_back('1');
    
    map mm;
    int flag = 1;
    for(int i = 0; i < n; i ++)
    {
        if(mm[s[i]])flag = 0;
        mm[s[i]] = 1;
    }
    
    if(flag)
    {
        int res = 1;
        for(int i = 1; i <= n; i ++)res *= i;
        cout << res;
        return 0;
    }
	
	dfs(0);
	
	cout << ans;
	
	return 0;
}

另外赛后学到一个函数,在全排列时还能自动去重,写法如下,记得用之前先sort一遍,不然会wa,比手动dfs快好多。

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'

using namespace std;

typedef pair PII;
typedef unsigned long long ull;
typedef long long ll;

int main()
{
    IOS
    string s;
    cin >> s;
    sort(s.begin(), s.end());
    int ans = 0;
    do
    {
        int f = 1;
        for(int i = 0; i < s.size() - 1; i ++)
        {
            if(s[i] == s[i + 1])
            {
                f = 0;
                break;
            }
        }
        ans += f;
    }while(next_permutation(s.begin(), s.end()));
        
    cout << ans << endl;
    
    return 0;
}

C

据说是三分,没学过三分,我的这种写法可能也是一种比较歪门邪道的东西,反正写出来了,赛后再补一补三分。

我是二分的时候判断mid这个点的单调性,根据单调性来判断到底是让r等于mid还是让l等于mid

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'

using namespace std;

typedef pair PII;
typedef unsigned long long ull;
typedef long long ll;

int main()
{
	double v, x, y;
	cin >> v >> x >> y;
	
	double ans = 2e18;
	double l = 0, r = 2e9;
	while(r - l >= 1e-7)
	{
		double mid = (l + r) / 2;
		double time = y / (v + mid * x) + mid;
        ans = min(ans, time);
		
        double mid1 = mid - 1e-8, mid2 = mid + 1e-8;
        double time1 = y / (v + mid1 * x) + mid1;
        double time2 = y / (v + mid2 * x) + mid2;
        
        if(time1 <= time2)r = mid;
        else if(time2 < time1) l = mid;
	}
	printf("%.6lf", ans);
	
	return 0;
}

赛后补的三分模板:

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'

using namespace std;

typedef pair PII;
typedef unsigned long long ull;
typedef long long ll;

double v, x, y;

double f(double mid)
{
	return y / (v + mid * x) + mid;
}

int main()
{
    cin >> v >> x >> y;
    
    double l = 0, r = 1e9;
    while(r - l > 1e-7)
    {
    	double mid = (r - l) / 3.0;
    	double m1 = l + mid;
    	double m2 = m1 + mid;
    	
    	if(f(m1) < f(m2))r = m2;
    	else l = m1;
	}
	
	printf("%.8lf", f(l));
    
    return 0;
}

你可能感兴趣的:(牛客,c++,算法,三分)