牛客练习赛45

A题
求三元组满足QAQ且三元组中的xyz不相邻。
模拟即可。每次找到一个a,答案为左边Q的数量乘以右边Q的数量。
注意longlong

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
const int maxn=5e3+10;
int arr[maxn];
int main()
{
    string s;
    cin>>s;
    ll ans=0;
    if(s.size()<3)
    {
        return 0*printf("0\n");
     } 
    int end=s.size()-1;
    if(s[0]=='Q')arr[0]=1;
    for(int i=1;i<s.size();i++)
    {    
        arr[i]=arr[i-1]+(s[i]=='Q');
    }
    for(int i=2;i<s.size()-2;i++)
    {
        if(s[i]=='A')
        {
            ans+=arr[i-2]*(arr[end]-arr[i+1]); 
        }
    }
    printf("%lld\n",ans);
}


B题
暴力模拟
连成线一共就那么几种方法,横着三种,竖着三种,对角线两个。
每一次按照题目的意思去模拟对比就行了。写的略嫌麻烦。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#define up(i,a,b)  for(int i=a;i
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
    char ch = getchar(); int x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
char grp[5][5];
int t;
bool judge()
{
    int ans1 = 0;
    int ans2 = 0;
    int ans3 = 0;
    up(i, 0, 3)
    {
        if (grp[i][0] == 'W')ans1++;
        if (grp[i][1] == 'W')ans2++;
        if (grp[i][2] == 'W')ans3++;
    }
    if (ans1 == 3||ans2==3||ans3==3)return true;
    ans1 = 0; ans2 = 0; ans3 = 0;
    up(i, 0, 3)
    {
        if (grp[0][i] == 'W')ans1++;
        if (grp[1][i] == 'W' )ans2++;
        if (grp[2][i] == 'W')ans3++;
    }
    if (ans1 == 3 || ans2 == 3 || ans3 == 3)return true;
    ans1 = 0; ans2 = 0; ans3 = 0;
    int temp = 0;
    int temp2 = 2;
    up(i, 0, 3)
    {
        if (grp[i][temp++] == 'W' )ans1++;
        if (grp[i][temp2--] == 'W')ans2++;
    }
    if (ans1 == 3 || ans2 == 3)return true;
    return false;
     
}
int main()
{
    t = read();
    while (t--)
    {
        int temp = 0;
        up(i, 0, 3)
        {
            scanf("%s", grp[i]);
        }
 
        bool flag = false;
        bool flag2=false;
        bool flag3 = false;
        up(i, 0, 3)
        {
            up(j, 0, 3)
            {
                if (grp[i][j] == '#') {
                    grp[i][j] = 'W';
                    if (judge())flag = true;
                    grp[i][j] = '#';
                }
            }
        }
        if (!flag) { cout << "Bob" << endl; continue; }
        up(i, 0, 3)
        {
            up(j, 0, 3)
            {
                if (grp[i][j] == 'W') {
                    grp[i][j] = 'B';
                    flag3 = false;
                    up(i, 0, 3)
                    {
                        up(j, 0, 3)
                        {
                            if (grp[i][j] == '#')
                            {
                                grp[i][j] = 'W';
                                if (judge())flag3 = true;
                                grp[i][j] = '#';
                            }
                        }
                    }
                    if (!flag3)flag2 = true;
                    grp[i][j] = 'W';
 
                }
            }
        }
        if (!flag2)cout << "Alice" << endl;
        else cout << "Emmm" << endl;
    }
    return 0;
}

C题 比上一题简单。
简单构造。

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{
    int n;
    scanf("%d",&n);
    if(n==1)
    {
        return 0*printf("0");
    }
    if(n%2==1)return 0*printf("-1");
    int mid=n/2,m=n-1,y=n-2;
    up(i,1,mid)
    {
        printf("%d ",m);
        m-=2;
    }
    printf("0 ");
    up(i,1,mid-1)
    {
        printf("%d ",y);
        y-=2;
    }
    return 0;
}

D题。对于位操作的题目。data structure是在骗人
这里or表示锁零,ans表示锁1。
我们借此就可以每一次贪心的去分出m个区间来。
每一次如果没有变的话就沿用上一次的答案。

#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{
    int n;
    scanf("%d",&n);
    if(n==1)
    {
        return 0*printf("0");
    }
    if(n%2==1)return 0*printf("-1");
    int mid=n/2,m=n-1,y=n-2;
    up(i,1,mid)
    {
        printf("%d ",m);
        m-=2;
    }
    printf("0 ");
    up(i,1,mid-1)
    {
        printf("%d ",y);
        y-=2;
    }
    return 0;
}

E题不会。


F题。最大闭合权。
感觉没有啥好说的。就是抄模板就行了

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#define up(i,a,b)  for(int i=a;i
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
    char ch = getchar(); int x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
int n, m;
const int N = 1e4;
struct edge { int to, cap, rev; };
vector<edge>grp[N];
int iter[N], level[N];
void addedge(int from, int to, int cap)
{
    grp[from].push_back(edge{ to,cap,(int)grp[to].size() });
    grp[to].push_back(edge{ from,0,(int)grp[from].size() - 1 });
}
void bfs(int s)
{
    queue<int >que;
    memset(level, -1, sizeof(level));
    que.push(s);
    level[s] = 0;
    while (!que.empty())
    {
        int temp = que.front();
        que.pop();
        up(i, 0, grp[temp].size())
        {
            edge &e = grp[temp][i];
            if (e.cap > 0 && level[e.to] < 0)
            {
                level[e.to] = level[temp] + 1;
                que.push(e.to);
            //  cout << "*" << endl;
            }
        }
    }
}
int dfs(int s, int t, int f)
{
    if (s == t)return f;
    for (int &i = iter[s]; i < grp[s].size(); i++)
    {
        edge &e = grp[s][i];
        if (e.cap > 0 && level[e.to] > level[s])
        {
            int d = dfs(e.to, t, min(f, e.cap));
            if (d > 0)
            {
                e.cap -= d;
                grp[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}
int min_flow(int s, int t, int f)
{
    int res = 0;
    int d = 0;
    while (1)
    {
        bfs(s);
        //cout << "*";
        if (level[t] < 0)return res;
        memset(iter, 0, sizeof(iter));
        while ((d = dfs(s, t, f)) > 0)
        {
            //cout << d << endl;
            res += d;
        }
    }
}
int getln(int x,int y)
{
    return (x-1)*n + y;
}
int main()
{
    n = read();
    m = read();
    int x = 0;
    int S = 0;
    int T = n * n + 2 * n + m + 1;
    int ans = 0;
    upd(i, 1, n)
    {
        upd(j, 1, n)
        {
            x = read();
            addedge(S, getln(i, j) + 2 * n, x);
            addedge(getln(i, j) + 2 * n, i, INF);
            addedge(getln(i, j) + 2 * n, j + n, INF);
            ans += x;
        }
    }
    upd(i, 1, n)
    {
        x = read();
        addedge(i, T, x);
    }
    upd(i, 1, n)
    {
        x = read();
        addedge(i + n, T, x);
    }
    int s1, t1, s2, t2, k;
    upd(i, 1, m)
    {
        s1 = read(), t1 = read(), s2 = read(), t2 = read(), k = read();
        addedge(S, 2 * n + n * n + i, k);
        addedge(2 * n + n * n + i, getln(s1, t1) + 2 * n, INF);
        addedge(2 * n + n * n + i, getln(s2, t2) + 2 * n, INF);
        ans += k;
    }
    //cout << ans << endl;
    cout << ans - min_flow(S, T, INF)<<endl;
    return 0;
 
}

你可能感兴趣的:(套题)