Codeforces_801

A.直接暴力就行了,先把能组合的按线性组合掉,再枚举剩下相邻没用过的。

#include<bits/stdc++.h>
using namespace std;

string s;
int vis[105] = {0};

int main()
{
    ios::sync_with_stdio(false);
    cin >> s;
    int ans = 0;
    for(int i = 1;i < s.length();i++)
    {
        if(vis[i-1] || vis[i])  continue;
        if(s[i-1] == 'V' && s[i] == 'K')
        {
            ans++;
            vis[i-1] = 1;
            vis[i] = 1;
        }
    }
    for(int i = 1;i < s.length();i++)
    {
        if(vis[i-1] || vis[i])  continue;
        if(s[i-1] == 'V' || s[i] == 'K')
        {
            ans++;
            break;
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

B.若存在,直接令y等于z就可以了。

#include<bits/stdc++.h>
using namespace std;

string s1,s2;

int main()
{
    ios::sync_with_stdio(false);
    cin >> s1 >> s2;
    string s3;
    int flag = 0;
    for(int
     i = 0;i < s1.length();i++)
    {
        if(s2[i] <= s1[i])  s3 = s3+s2[i];
        else
        {
            flag = 1;
        }
    }
    if(flag)    cout << -1<< endl;
    else    cout << s3 << endl;

    return 0;
}
View Code

C.二分,先判断是否能永久运行,若不行,二分答案。

#include<bits/stdc++.h>
using namespace std;

int n,p,a[100005],b[100005];

bool ok(double x)
{
    double sum = 0;
    for(int i = 1;i <= n;i++)
    {
        if(a[i]*x > b[i])   sum += a[i]*x-b[i];
    }
    if(sum < p*x)   return 1;
    return 0;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> p;
    long long sum = 0;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i] >> b[i];
        sum += a[i];
    }
    if(sum <= p)
    {
        cout << -1 << endl;
        return 0;
    }
    double l = 0,r = 1e18;
    while(abs(l-r) > 1e-5)
    {
        double mid = (l+r)/2;
        if(ok(mid)) l = mid;
        else r = mid;
    }
    cout << l << endl;
    return 0;
}
View Code

D.枚举每一组相邻3个顶点,取中间点到两边点构成直线的距离的最小值,再除以2。

#include<bits/stdc++.h>
using namespace std;

int n;
double a[1005],b[1005];

double f(double x1,double y1,double x2,double y2,double x3,double y3)
{
    double aa = y2-y1,bb = x1-x2,cc = x2*y1-x1*y2;
    return abs(aa*x3+bb*y3+cc)/sqrt(aa*aa+bb*bb);
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i = 1;i <= n;i++)   cin >> a[i] >> b[i];
    double ans = 1e18;
    for(int i = 1;i <= n;i++)
    {
        int j = i+1,k = j+1;
        if(j > n)   j -= n;
        if(k > n)   k -= n;
        ans = min(ans,f(a[i],b[i],a[j],b[j],a[k],b[k]));
        ans = min(ans,f(a[i],b[i],a[k],b[k],a[j],b[j]));
        ans = min(ans,f(a[j],b[j],a[k],b[k],a[i],b[i]));
    }
    cout << fixed << setprecision(8) << ans/2 << endl;
    return 0;
}
View Code

E.令p[i]为第i次出现的前i个元素积(%m),问题是如何构造最长的p序列。

设元素i,j,则①i可以向j转移的条件是gcd(m, i)丨gcd(m, j)

      ②i,j可以互相转移的条件是gcd(m, i)=gcd(m, j)

于是,我们把每一个gcd看成点,同一个gcd间的元素可以相互转化,然后构成图,dfs找最长路线。

有了p序列,pi-1*x%p==pi(P0=1),求解每一个x输出即可,这个可以用扩展欧几里德解决。

0这个点可以放到最后特殊处理。

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int n,m,cantbe[200005] = {0},vis[200005] = {0},dp[200005],nextt[200005];
vector<int> v[200005];

LL ex_gcd(LL a,LL b,LL &x,LL &y)
{
    int d = a;
    if(!b)
    {
        x = 1;
        y = 0;
    }
    else
    {
        d = ex_gcd(b,a%b,y,x);
        y -= (a/b)*x;
    }
    return d;
}

LL f(LL a,LL b,LL n)
{
    LL d,x,y;
    d = ex_gcd(a,n,x,y);
    x = (x%n+n)%n;
    return (x*b/d)%n;
}

int dfs(int now)
{
    if(dp[now] > 0)    return dp[now];
    dp[now] = v[now].size();
    for(int i = now*2;i < m;i += now)
    {
        if(v[i].size() == 0)    continue;
        int t = dfs(i);
        if(dp[now] < v[now].size()+t)
        {
            dp[now] = t+v[now].size();
            nextt[now] = i;
        }
    }
    return dp[now];
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for(int i = 1;i <= n;i++)
    {
        int x;
        cin >> x;
        cantbe[x] = 1;
    }
    for(int i = 1;i < m;i++)
    {
        if(!cantbe[i]) v[__gcd(i,m)].push_back(i);
    }
    memset(dp,0,sizeof(dp));
    memset(nextt,-1,sizeof(nextt));
    dfs(1);
    int now =  max_element(dp,dp+m)-dp;
    cout << dp[now]+(cantbe[0] == 0) << endl;
    int last = 1;
    while(now != -1)
    {
        for(int i = 0;i < v[now].size();i++)
        {
            int t = v[now][i];
            cout << f(last,t,m) << " ";
            last = t;
        }
        now = nextt[now];
    }
    if(cantbe[0] == 0)   cout << 0 << endl;
    else    cout << endl;
    return 0;
}
View Code

 

原文地址:https://www.cnblogs.com/zhurb/p/6731381.html